Files
coop/.agents/skills/gpui-test/examples.md
Ren Amamiya 40d726c986 feat: refactor to use gpui event instead of local state (#18)
Reviewed-on: #18
Co-authored-by: Ren Amamiya <reya@lume.nu>
Co-committed-by: Ren Amamiya <reya@lume.nu>
2026-03-10 08:19:02 +00:00

3.3 KiB

Testing Best Practices

Test Organization

Group related tests in modules:

#[cfg(test)]
mod tests {
    use super::*;

    mod entity_tests {
        use super::*;

        #[gpui::test]
        fn test_creation() { /* ... */ }

        #[gpui::test]
        fn test_updates() { /* ... */ }
    }

    mod async_tests {
        use super::*;

        #[gpui::test]
        async fn test_async_ops() { /* ... */ }
    }

    mod distributed_tests {
        use super::*;

        #[gpui::test]
        fn test_multi_app() { /* ... */ }
    }
}

Setup and Teardown

Use helper functions for common setup:

fn create_test_counter(cx: &mut TestAppContext) -> Entity<Counter> {
    cx.new(|cx| Counter::new(cx))
}

#[gpui::test]
fn test_counter_operations(cx: &mut TestAppContext) {
    let counter = create_test_counter(cx);

    // Test operations
}

Assertions

Use descriptive assertions:

#[gpui::test]
fn test_counter_bounds(cx: &mut TestAppContext) {
    let counter = create_test_counter(cx);

    // Test upper bound
    for _ in 0..100 {
        counter.update(cx, |counter, cx| {
            counter.increment(cx);
        });
    }

    let count = counter.read_with(cx, |counter, _| counter.count);
    assert!(count <= 100, "Counter should not exceed maximum");

    // Test lower bound
    for _ in 0..200 {
        counter.update(cx, |counter, cx| {
            counter.decrement(cx);
        });
    }

    let count = counter.read_with(cx, |counter, _| counter.count);
    assert!(count >= 0, "Counter should not go below minimum");
}

Performance Testing

Test performance characteristics:

#[gpui::test]
fn test_operation_performance(cx: &mut TestAppContext) {
    let component = cx.new(|cx| MyComponent::new(cx));

    let start = std::time::Instant::now();

    // Perform many operations
    for i in 0..1000 {
        component.update(cx, |comp, cx| {
            comp.perform_operation(i, cx);
        });
    }

    let elapsed = start.elapsed();
    assert!(elapsed < Duration::from_millis(100), "Operations should complete quickly");
}

Running Tests

Basic Test Execution

# Run all tests
cargo test

# Run specific test
cargo test test_counter_operations

# Run tests in a specific module
cargo test entity_tests::

# Run with output
cargo test -- --nocapture

Test Configuration

Enable test-support feature for GPUI tests:

[features]
test-support = ["gpui/test-support"]
cargo test --features test-support

Advanced Test Execution

# Run tests with iterations for property testing
cargo test -- --test-threads=1

# Run tests matching a pattern
cargo test test_async

# Run tests with backtrace on failure
RUST_BACKTRACE=1 cargo test

CI/CD Integration

For continuous integration:

# .github/workflows/test.yml
name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: dtolnay/rust-toolchain@stable
      - name: Run tests
        run: cargo test --features test-support

GPUI's testing framework provides deterministic, fast, and comprehensive testing capabilities that mirror real application behavior while providing the control needed for thorough testing of complex UI and async scenarios.