# Testing Guide
This document describes the comprehensive testing infrastructure for the x11-overlay project.
## Overview
The project uses a multi-layered testing approach following Rust best practices:
- **Unit Tests**: Test individual functions and methods in isolation
- **Integration Tests**: Test interactions between components
- **Property-based Tests**: Use `proptest` to verify mathematical properties
- **Benchmarks**: Performance testing using `criterion`
## Test Categories
### Unit Tests
Located within each module using `#[cfg(test)]` blocks.
#### Animation Module Tests
**Easing Functions** (`src/animation/easing.rs`)
- Boundary condition testing (t=0 and t=1)
- Mathematical accuracy verification
- Monotonicity testing for ease-in functions
- Symmetry validation for ease-in-out functions
- Property-based testing for edge cases
**Timing Components** (`src/animation/timing.rs`)
- Timer delta calculation accuracy
- Timeline progress tracking
- Looping animation behavior
- Frame limiter functionality
#### Graphics Module Tests
**Color System** (`src/graphics/renderer.rs`)
- ARGB color encoding/decoding
- Color constant validation
- Alpha channel manipulation
- Component extraction accuracy
#### UI Module Tests
**Status Indicators** (`src/ui/indicators.rs`)
- Position calculation for different screen sizes
- Animation property application
- Bounds checking and validation
- Position enum variants
### Integration Tests
Located in the `tests/` directory.
**Simple Integration** (`tests/simple_integration.rs`)
- Cross-module functionality
- Easing function integration
- Timeline with easing combinations
- Color interpolation workflows
- Screen coordinate calculations
### Property-based Tests
Using `proptest` for mathematical verification:
- **Easing Functions**: Ensure all easing functions produce finite values
- **Color Components**: Verify ARGB encoding roundtrip accuracy
- **Position Bounds**: Validate screen coordinate constraints
- **Timeline Progress**: Ensure progress stays within [0.0, 1.0] bounds
### Benchmarks
Located in the `benches/` directory.
**Animation Benchmarks** (`benches/animation_bench.rs`)
- Easing function performance
- Interpolation speed
- Timeline update efficiency
- Stress testing with multiple timelines
**Rendering Benchmarks** (`benches/rendering_bench.rs`)
- Color creation and manipulation
- Rectangle operations
- UI component performance
- Alpha blending calculations
## Running Tests
### Unit Tests
```bash
# Run all tests
cargo test
# Run specific module tests
cargo test animation::easing
cargo test graphics::renderer
cargo test ui::indicators
# Run with output
cargo test -- --nocapture
```
### Integration Tests
```bash
# Run integration tests only
cargo test --test simple_integration
# Run specific integration test
cargo test test_easing_function_integration
```
### Property-based Tests
```bash
# Run property tests (included in unit tests)
cargo test property_tests
# Run with specific seed for reproducibility
PROPTEST_CASES=1000 cargo test property_tests
```
### Benchmarks
```bash
# Run all benchmarks
cargo bench
# Run specific benchmark suite
cargo bench animation_bench
cargo bench rendering_bench
# Generate benchmark reports
cargo bench -- --output-format html
```
## Test Configuration
### Dependencies
Test dependencies are configured in `Cargo.toml`:
```toml
[dev-dependencies]
proptest = "1.4" # Property-based testing
mockall = "0.12" # Mocking framework
criterion = "0.5" # Benchmarking
approx = "0.5" # Floating-point comparisons
rstest = "0.18" # Parameterized tests
```
### Profiles
Custom test profile for optimized test builds:
```toml
[profile.test]
opt-level = 1
debug = true
```
## Writing Tests
### Unit Test Guidelines
1. **Test Naming**: Use descriptive names starting with `test_`
2. **Isolation**: Each test should be independent
3. **Coverage**: Test both success and failure cases
4. **Precision**: Use `approx::assert_abs_diff_eq!` for floating-point comparisons
Example:
```rust
#[test]
fn test_cubic_easing_boundaries() {
assert_abs_diff_eq!(cubic::ease_in(0.0), 0.0, epsilon = 1e-6);
assert_abs_diff_eq!(cubic::ease_in(1.0), 1.0, epsilon = 1e-6);
}
```
### Property-based Test Guidelines
1. **Range Definition**: Use appropriate ranges for inputs
2. **Property Verification**: Test mathematical properties
3. **Error Messages**: Provide clear failure descriptions
Example:
```rust
proptest! {
#[test]
fn test_easing_functions_stay_finite(t in 0.0f32..=1.0f32) {
assert!(linear(t).is_finite());
assert!(quad::ease_in(t).is_finite());
}
}
```
### Benchmark Guidelines
1. **Black Box**: Use `black_box()` to prevent optimization
2. **Realistic Data**: Use representative input sizes
3. **Multiple Scenarios**: Test different use cases
Example:
```rust
fn bench_easing_functions(c: &mut Criterion) {
let mut group = c.benchmark_group("easing_functions");
group.bench_function("cubic_ease_in_out", |b| {
b.iter(|| {
for i in 0..1000 {
let t = i as f32 / 1000.0;
black_box(cubic::ease_in_out(black_box(t)));
}
})
});
}
```
## Test Coverage
Current test coverage includes:
### Animation Module (95%+)
- ✅ All easing functions (linear, quad, cubic, sine, bounce, elastic)
- ✅ Interpolation function
- ✅ Timeline progress and completion
- ✅ Timer delta calculations
- ✅ Frame limiter functionality
### Graphics Module (90%+)
- ✅ Color creation and constants
- ✅ ARGB encoding/decoding
- ✅ Rectangle operations
- ⚠️ Renderer methods (requires X11 connection)
### UI Module (85%+)
- ✅ Status indicator creation
- ✅ Position calculations
- ✅ Animation property application
- ✅ Bounds checking
- ⚠️ Rendering methods (requires X11 connection)
## Examples
The `examples/` directory contains practical demonstrations:
- `easing_demo.rs`: Demonstrates different easing functions
- `timeline_demo.rs`: Shows timeline usage patterns
- `color_demo.rs`: Color system examples
Run examples with:
```bash
cargo run --example easing_demo
cargo run --example timeline_demo
cargo run --example color_demo
```
## Continuous Integration
Tests are configured to run automatically in CI environments:
1. **Unit Tests**: Run on every commit
2. **Integration Tests**: Run on pull requests
3. **Benchmarks**: Run on performance-related changes
4. **Property Tests**: Run with extended case counts
## Troubleshooting
### Common Issues
1. **Floating-point Precision**: Use `approx` crate for comparisons
2. **X11 Dependencies**: Some tests require display server for rendering
3. **Timing Tests**: May be flaky in CI environments
4. **Property Test Failures**: Check seed values for reproducibility
### Debug Tips
1. Use `-- --nocapture` to see print output
2. Run single tests with specific names
3. Use `RUST_BACKTRACE=1` for detailed error traces
4. Set `PROPTEST_CASES` for property test tuning