Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Testing Philosophy

The Hierarchy

Tests are prioritized by the strength of the guarantee they provide:

  1. Determinism tests — Same seed + same input = bit-identical output. These are the proof that the system works. Highest priority.
  2. Property-based testsproptest generates random inputs and verifies invariants hold for all of them. Catches edge cases humans miss.
  3. Snapshot testsinsta for serialization formats (WARC++, JSON, index entries). Snapshots are reviewed artifacts.
  4. Integration tests — Real HTTP via wiremock, real storage backends, real index queries.
  5. Unit tests — Standard #[test] for isolated logic.

No Mocking Core Interfaces

The storage layer, index, and envelope are the system’s integrity boundaries. Never mock them. Use real implementations with in-memory backends:

#![allow(unused)]
fn main() {
// Correct: real implementation, in-memory backend
let store = InMemoryBlobStore::new();
let index = InMemoryIndex::new();

// Wrong: mocked storage that always returns Ok
// let store = MockBlobStore::new();  // DON'T
}

Test Naming

test_{what}_{condition}_{expected_outcome}

Examples:

  • test_frontier_with_same_seed_produces_identical_order
  • test_artifact_hash_changes_when_content_differs
  • test_storage_put_get_roundtrip_preserves_content

Adversarial Testing

Every adversarial input must produce a classified error, never a panic or silent corruption:

  • Malformed HTTP responses
  • Truncated connections mid-transfer
  • DNS resolution failures
  • TLS certificate anomalies
  • Content that attempts to exploit parsers (polyglot files, zip bombs)

Test Coverage

301 tests across 21 test files, covering all 15 crates. The simulation framework proves determinism at 10,000 pages with zero divergence.