Testing Guide
Merlon has tests at every layer: Go, Rust, TypeScript, and Proto. This document covers how to run each and the overall testing strategy.
Running tests per component
Go (API)
cd api && go test ./...
With coverage:
cd api && go test -cover ./...
Rust (Engine)
cd engine && cargo test
UI (TypeScript / React)
cd ui && npm run test
Proto (Protocol Buffers)
cd proto && buf lint
Detecting breaking changes:
cd proto && buf breaking --against '.git#branch=main'
Running everything
make test
make test runs the Go tests, Rust tests, UI tests, and buf lint together.
CI uses the same target.
Testing strategy (TDD)
Feature work and bug fixes follow TDD (test-driven development).
- Write the test — write a test that expresses the expected behavior first (confirm it fails).
- Implement — write the minimal code needed to make the test pass.
- Refactor — clean up while keeping the test green.
Emphasis by layer
- Engine (Rust) — CDD scoring, TM evaluation, and screening are the core business logic. To uphold reproducibility of decision rationale (Auditability First), tests pin the determinism of output for identical input.
- API (Go) — CRUD and orchestration. Tests verify service-boundary contracts and that failures fall toward alerting rather than silence (Fail-Alert).
- Proto — Contract Stability (12+ months of backward compatibility) is
mechanically enforced with
buf breaking. - UI — component-level tests plus user-flow tests for the investigation workflow.
Follow existing patterns
New tests should follow the existing test framework, naming conventions, and
patterns in each directory. Go uses the standard testing package, Rust
uses #[cfg(test)] modules, and the UI follows its existing test-runner
configuration.