# Phase 6: Testing & Validation ## Overview Phase 6 implements comprehensive testing and validation for the map rendering pipeline, ensuring correctness, performance, and robustness. ## Test Categories ### 1. Integration Tests **Location:** `crates/apps/map/tests/` Integration tests verify end-to-end functionality of the tile decoding pipeline: - `tile_decode_integration.rs` - Tests complete tile decoding from JSON/MVT to renderable buffers - `render_graph_tests.rs` - Tests the trait-based render graph system **Coverage:** - Simple and complex geometry decoding - Security limit enforcement - Error handling for malformed input - Various OSM feature types (buildings, roads, water, POIs) - Different zoom levels - Unicode tag handling - Geometry tessellation correctness **Run integration tests:** ```bash cargo test --package nigig-map --test tile_decode_integration cargo test --package nigig-map --test render_graph_tests ``` ### 2. Unit Tests **Location:** Inline in source modules Each module contains unit tests for its specific functionality: - `mvt_parser.rs` - MVT binary parsing tests - `overpass_parser.rs` - JSON parsing tests - `tessellation.rs` - Geometry tessellation tests - `tile_decode.rs` - Integration of parser modules **Run unit tests:** ```bash cargo test --package nigig-map --lib ``` ### 3. Performance Benchmarks **Location:** `crates/apps/map/benches/` Benchmarks measure performance of critical paths: - `tile_decode_bench.rs` - Benchmarks for tile decoding performance **Benchmark Categories:** - Simple JSON decoding - Scaling with feature count (10, 50, 100, 500, 1000 features) - MVT parsing performance - Geometry tessellation - POI extraction (100 POIs) - Label extraction (50 labels) **Run benchmarks:** ```bash cargo bench --package nigig-map ``` **Run specific benchmark:** ```bash cargo bench --package nigig-map -- "decode_scaling" ``` ### 4. Fuzz Testing **Location:** `crates/apps/map/fuzz/` Fuzz testing finds crashes and edge cases with random input: - `fuzz_mvt_parser.rs` - Fuzz MVT binary parser - `fuzz_overpass_parser.rs` - Fuzz JSON parser - `fuzz_tile_decode.rs` - Fuzz complete pipeline **Setup:** ```bash # Install cargo-fuzz cargo install cargo-fuzz # Run fuzz target (example: MVT parser) cd crates/apps/map cargo fuzz run fuzz_mvt_parser -- -max_total_time=60 ``` **Fuzz for 5 minutes:** ```bash cargo fuzz run fuzz_overpass_parser -- -max_total_time=300 ``` ### 5. Visual Regression Tests **Location:** `crates/apps/map/tests/visual/` (future) Visual regression tests compare rendered tiles against golden images: - Render test tiles with known data - Compare output against reference images - Detect visual regressions **Note:** Visual tests require a rendering environment and are not yet implemented. ## Test Data ### Test Fixtures Test data is embedded in test files or loaded from: - `crates/apps/map/tests/fixtures/` (future) ### Sample Data Integration tests use realistic OSM data: - Amsterdam city center tiles - Various feature types (buildings, roads, water, POIs) - Edge cases (malformed data, missing nodes, Unicode) ## Running All Tests ### Quick Test Suite Run all unit and integration tests: ```bash cargo test --package nigig-map ``` ### Full Test Suite Run all tests including benchmarks: ```bash # Unit and integration tests cargo test --package nigig-map # Benchmarks cargo bench --package nigig-map # Fuzz testing (optional, requires cargo-fuzz) cd crates/apps/map cargo fuzz run fuzz_tile_decode -- -max_total_time=60 ``` ### CI Test Suite For continuous integration: ```bash # Run tests with coverage cargo test --package nigig-map --no-fail-fast # Check for warnings cargo clippy --package nigig-map -- -D warnings # Format check cargo fmt --package nigig-map -- --check ``` ## Test Coverage ### Current Coverage | Module | Unit Tests | Integration Tests | Benchmarks | Fuzz Targets | |--------|-----------|-------------------|------------|--------------| | mvt_parser | ✅ | ✅ | ✅ | ✅ | | overpass_parser | ✅ | ✅ | ✅ | ✅ | | tessellation | ✅ | ✅ | ✅ | - | | tile_decode | ✅ | ✅ | ✅ | ✅ | | render_graph | ✅ | ✅ | - | - | ### Coverage Goals - **Unit tests:** 90%+ line coverage - **Integration tests:** All public APIs tested - **Benchmarks:** All critical paths benchmarked - **Fuzz testing:** All parsers fuzzed ## Continuous Integration ### GitHub Actions Workflow (future) ```yaml name: Test Suite on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: stable - name: Run tests run: cargo test --package nigig-map - name: Run clippy run: cargo clippy --package nigig-map -- -D warnings - name: Check formatting run: cargo fmt --package nigig-map -- --check bench: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: stable - name: Run benchmarks run: cargo bench --package nigig-map fuzz: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: nightly - name: Install cargo-fuzz run: cargo install cargo-fuzz - name: Fuzz MVT parser run: cd crates/apps/map && cargo fuzz run fuzz_mvt_parser -- -max_total_time=300 ``` ## Performance Regression Detection ### Benchmark Tracking Benchmarks are tracked over time to detect performance regressions: 1. Run benchmarks on each commit 2. Compare against baseline 3. Alert if performance degrades >10% ### Baseline Performance Current baseline (Phase 6): - Simple JSON decode: ~2ms - 100 features: ~10ms - 1000 features: ~100ms - MVT parse: ~1ms - Tessellation: ~5ms ## Debugging Failed Tests ### Verbose Output Run tests with verbose output: ```bash cargo test --package nigig-map -- --nocapture ``` ### Single Test Run a specific test: ```bash cargo test --package nigig-map test_decode_simple_json ``` ### Backtrace Enable backtraces for panics: ```bash RUST_BACKTRACE=1 cargo test --package nigig-map ``` ## Adding New Tests ### Unit Test Add to the module's `#[cfg(test)]` section: ```rust #[cfg(test)] mod tests { use super::*; #[test] fn test_new_feature() { // Test implementation assert!(result.is_ok()); } } ``` ### Integration Test Add to `crates/apps/map/tests/`: ```rust use nigig_map::tile_decode::build_tile_buffers_from_body; #[test] fn test_integration_scenario() { // Test implementation } ``` ### Benchmark Add to `crates/apps/map/benches/`: ```rust use criterion::{criterion_group, criterion_main, Criterion}; fn bench_new_feature(c: &mut Criterion) { c.bench_function("new_feature", |b| { b.iter(|| { // Benchmark implementation }) }); } criterion_group!(benches, bench_new_feature); criterion_main!(benches); ``` ## Test Best Practices 1. **Test edge cases:** Empty input, malformed data, boundary values 2. **Test error paths:** Ensure errors are handled gracefully 3. **Use realistic data:** Test with real OSM data when possible 4. **Keep tests fast:** Unit tests should complete in <100ms 5. **Document tests:** Add comments explaining what is being tested 6. **Avoid flaky tests:** Tests should be deterministic 7. **Clean up resources:** Ensure tests don't leak memory or file handles ## Future Improvements 1. **Property-based testing:** Use `proptest` for property-based testing 2. **Snapshot testing:** Use `insta` for snapshot testing of complex outputs 3. **Mutation testing:** Use `cargo-mutants` to test test quality 4. **Code coverage:** Integrate `cargo-tarpaulin` for coverage reports 5. **Visual regression:** Implement visual regression testing with golden images 6. **Load testing:** Test with large real-world tiles (10,000+ features) ## Conclusion Phase 6 provides comprehensive testing and validation for the map rendering pipeline, ensuring correctness, performance, and robustness. The test suite covers unit tests, integration tests, benchmarks, and fuzz testing, providing confidence in the codebase quality.