tileserver-rs has a comprehensive test suite covering unit tests, integration tests, and end-to-end rendering tests.
cargo test
# Unit tests (overlay parsing, color parsing, etc.)
cargo test render::overlay
# Integration tests (config loading, source validation)
cargo test --test integration
# E2E rendering tests (snapshot testing)
cargo test --test e2e_rendering
src/
├── render/
│ └── overlay.rs # Unit tests for overlay parsing (52 tests)
│
tests/
├── config.test.toml # Test configuration using data/ fixtures
├── integration.rs # Integration tests (45 tests)
├── e2e_rendering.rs # E2E rendering tests (13 tests)
└── snapshots/ # Snapshot artifacts
├── *.snap # JSON snapshots (insta)
└── *.png # Generated test images
The test suite uses fixtures from the data/ directory:
data/
├── fonts/
│ ├── Noto Sans Medium/ # PBF glyph files
│ └── Noto Sans Regular/
├── styles/
│ └── protomaps-light/
│ └── style.json
└── tiles/
├── protomaps-sample.pmtiles
└── zurich_switzerland.mbtiles
We use insta for snapshot testing. Snapshots capture expected JSON output and rendered images for regression testing.
# Run tests and see snapshot diffs
cargo insta test
# Interactive review of changes
cargo insta review
# Accept all new/changed snapshots
cargo insta test --accept
cargo install cargo-insta
Unit tests are embedded in the source files using #[cfg(test)] modules.
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_hex_color_6digit() {
let color = parse_hex_color("ff5500").unwrap();
assert_eq!(color, [255, 85, 0, 255]);
}
#[test]
fn test_parse_marker_with_label() {
let marker = parse_marker("pin-s-a+ff0000(10,20)").unwrap();
assert_eq!(marker.label, Some("a".to_string()));
assert_eq!(marker.color, [255, 0, 0, 255]);
}
}
Integration tests verify the system works correctly with real tile sources and configurations.
#[tokio::test]
async fn test_load_sources_from_config() {
let config = Config::load(Path::new("tests/config.test.toml")).unwrap();
let manager = SourceManager::from_config(&config).await.unwrap();
assert!(manager.get_source("protomaps").is_some());
assert!(manager.get_source("zurich").is_some());
}
E2E tests generate actual PNG images and compare them against stored snapshots.
Test images are saved to tests/snapshots/:
| File | Description |
|---|---|
marker_red_small.png | Small red marker |
marker_green_*.png | Green markers (s/m/l sizes) |
path_blue_diagonal.png | Blue diagonal path |
path_magenta_diamond.png | Diamond shape with fill |
polyline_google_example.png | Decoded Google polyline |
combined_paths_markers.png | Multiple overlays |
Add tests in the same file as the code being tested:
// src/render/overlay.rs
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_your_new_feature() {
// Test implementation
}
}
Add tests to tests/integration.rs:
#[tokio::test]
async fn test_your_integration_scenario() {
let config = Config::load(Path::new("tests/config.test.toml")).unwrap();
// Test against real fixtures
}
Add tests to tests/e2e_rendering.rs:
#[test]
fn test_render_new_overlay() {
let overlays = vec![
parse_marker("pin-s+ff0000(10,20)").unwrap(),
];
let image = render_overlay_to_image(&overlays, 256, 256);
save_test_image(&image, "new_overlay.png");
// Verify image properties
assert!(image.width() > 0);
}
Tests run automatically on every pull request via GitHub Actions. The CI workflow:
cargo test for all test categoriesTo update snapshots after intentional changes:
cargo insta test --accept
git add tests/snapshots/
git commit -m "test: update snapshots"