Part 9 of 10 23 Jan 2026 By Raj Patil 25 min read

Part 9: Testing Freya Applications - Headless & Integration Tests

Part 9 of the Freya Rust GUI series. Ensure reliability by mastering testing strategies, from unit logic to headless component testing.

Intermediate #rust #freya #testing #unit-tests #integration-tests #headless-testing #qa
Building Native GUIs with Rust & Freya 9 / 10

Testing Freya Applications

Testing ensures your application works correctly. I’ll explore testing strategies for Freya apps.

Headless Testing

Freya provides a TestingRunner for headless testing of components.

First, add freya-testing to your dev-dependencies:

[dev-dependencies]
freya-testing = "0.4"

Then write your test:

use freya::prelude::*;
use freya_testing::TestingRunner;

fn counter_app() -> impl IntoElement {
    let mut count = use_state(|| 0);

    rect()
        .on_click(move |_| *count.write() += 1)
        .child(format!("Count: {}", count.read()))
}

#[test]
fn test_counter() {
    let mut utils = TestingRunner::new(
        counter_app,
        (500.0, 500.0).into(),
        |r| r, // Context provider (optional)
        1.0 // Scale factor
    );

    // Initial render
    utils.wait_for_update().unwrap();
    
    // Check initial state (text content)
    let root = utils.root().get(0);
    // Note: Traversing the node tree depends on internal structure, 
    // but typically you check the layout node's text or properties.
    // For simplicity in this example, we assume we can inspect the generated layout/text.
    
    // Simulate click
    utils.click_cursor((10.0, 10.0)); // Click at 10,10 where the rect is
    
    // Wait for update
    utils.wait_for_update().unwrap();
    
    // Assert new state (pseudo-code as actual assertion depends on node inspection API)
    // assert!(text_content.contains("Count: 1"));
}

Unit Testing Logic

You can test non-UI logic (like hooks) by isolating them or using standard Rust unit tests.

#[test]
fn test_logic() {
    let mut count = 0;
    count += 1;
    assert_eq!(count, 1);
}

Snapshot Testing

For visual regression testing, you currently need to capture the rendering output (e.g., Skia surface bytes) if using a custom runner, or rely on logic verification via TestingRunner.

What’s Next

In my final tutorial, I’ll cover deployment and distribution.

Summary