Macro's Testing Strategy: Local e2e, Integration, and Unit Test Architecture Explained
Macro's testing strategy uses a three-layer approach: fast unit tests with cargo test, cross-crate integration tests with cargo nextest, and full-stack local e2e tests orchestrated via xtask-local with Docker Compose services.
The macro-inc/macro codebase implements a disciplined, layered testing architecture that balances developer velocity with production confidence. This article examines how the repository structures its local end-to-end tests, integration tests, and unit tests, including the exact commands, source files, and safety mechanisms that make this strategy work.
Unit Tests: Fast, Isolated Feedback
Unit tests in Macro follow Rust's standard #[cfg(test)] pattern, embedded directly within each crate. These tests validate individual functions and types without external dependencies.
Run unit tests across the workspace:
just test
Many crates also include TypeScript/JavaScript tests under packages/…/test-utils for shared front-end logic. This dual-language approach ensures that utility code is verified in both Rust and TypeScript contexts where applicable.
Integration Tests: Cross-Crate Validation
Integration tests verify interactions between crates and external services (databases, Kafka, S3). Macro uses cargo-nextest as its test runner for this layer, selected via a custom filter.
Running Integration Tests
just test-integration
This invokes cargo nextest with a workspace-level configuration. The CI filter lives in tooling/xtask/crates/xtask_nextest_filter/src/test.rs, where the test suite is identified:
// tooling/xtask/crates/xtask_nextest_filter/src/test.rs
// Lines 17-20: Integration test selection logic used by CI
The filter ensures that integration tests—typically slower and requiring external state—run separately from unit tests, preserving fast feedback loops.
Local End-to-End Tests: Full-Stack Validation
The local e2e test layer is Macro's most comprehensive testing tier. It spins up the entire Micro-service architecture—Postgres, Kafka, S3 (via LocalStack), and all application services—within a local Docker environment.
Core Implementation
The e2e workflow is defined in tooling/xtask/crates/xtask_local/src/local/e2e.rs (lines 15-33), which implements the xtask-local binary's e2e command. A wrapper script at tooling/scripts/run-local-e2e.sh (lines 18-22) handles environment setup:
# Full local e2e suite (all services + UI tests)
just local-e2e-all
# UI-only e2e tests
just local-e2e-ui
# Specific suite selection
just local-e2e --suite web
CLI Argument Parsing
The xtask-local binary parses suite arguments in tooling/xtask/crates/xtask_local/src/local/cli.rs (lines 53-56), matching the LocalE2e variant to forward tests to the appropriate runner:
cargo testfor Rust back-end testsvitestfor front-end tests
E2E Safety Mechanisms and Seed Data
Macro's e2e tests include critical safeguards to prevent accidental data destruction.
Database URL Validation
Before any seed operation, the code validates that DATABASE_URL points to a local instance. This logic resides in tooling/seed_cli/src/entity/scenario/mod.rs (lines 439-471):
// Example: Guard that prevents accidental e2e seeding against a non-local DB
fn validate_local_e2e_database_url(database_url: &str) -> anyhow::Result<()> {
let url = url::Url::parse(database_url)?;
let host = url.host_str().unwrap_or_default();
if !(host == "localhost" || host == "127.0.0.1" || host == "postgres") {
anyhow::bail!(
"refusing to run local-e2e-smoke seed against DATABASE_URL host={:?}",
host
);
}
Ok(())
}
This function explicitly rejects any host that isn't localhost, 127.0.0.1, or postgres (the Docker Compose service name).
Seed Data Loading
The e2e suite populates the environment with fixture data from tooling/seed_cli/seed/local_e2e/:
| File | Purpose |
|---|---|
manifest.json |
Test scenario definitions |
users.sql / related fixtures |
Initial user accounts |
channel_messages.sql |
Sample conversation data |
The seed implementation in tooling/seed_cli/src/entity/scenario/mod.rs (lines 532-537) logs each step:
tracing::info!("seeding local e2e smoke documents");
// ... creates users, channels, messages
A final "ready" line signals that the environment is prepared for test execution.
Docker Compose Infrastructure
The local e2e environment is defined in docker/docker-compose.local-e2e.yml (lines 6-15), which specifies:
- Postgres for relational data
- LocalStack for S3-compatible object storage
- Kafka for event streaming
- Service-specific overrides for e2e test configurations
This composition mirrors production infrastructure while remaining fully containerized and reproducible on any developer machine.
CI Integration
Macro's continuous integration pipeline leverages the justfile targets for consistent test execution:
| CI Job | Command | Purpose |
|---|---|---|
| Unit + Integration | just test |
Fast feedback on code changes |
| Full e2e | just local-e2e-all |
Complete stack validation against temporary Docker environment |
The separation allows PRs to receive rapid unit/integration feedback while full e2e runs provide merge confidence.
Summary
- Unit tests (
cargo test,just test) provide millisecond-level feedback on isolated functions. - Integration tests (
cargo nextest,just test-integration) validate cross-crate API contracts with external services. - Local e2e tests (
just local-e2e-*) exercise the full stack viaxtask-localwith Docker Compose infrastructure. - Safety guards in
tooling/seed_cli/src/entity/scenario/mod.rsprevent accidental production database seeding. - Seed data in
tooling/seed_cli/seed/local_e2e/ensures reproducible test scenarios.
Frequently Asked Questions
How do I run only the back-end e2e tests without the UI?
Use just local-e2e --suite rust or cargo test within the specific crate. The --suite argument is parsed in tooling/xtask/crates/xtask_local/src/local/cli.rs and forwarded to the Rust test runner.
What prevents the e2e tests from connecting to my production database?
The validate_local_e2e_database_url function in tooling/seed_cli/src/entity/scenario/mod.rs enforces a whitelist of localhost, 127.0.0.1, and postgres hosts. Any other DATABASE_URL host triggers an immediate error before any seeding occurs.
Why does Macro use cargo nextest instead of the default test runner?
Nextest provides faster execution through parallelization, clearer output formatting, and programmable test filtering. The custom filter in tooling/xtask/crates/xtask_nextest_filter/src/test.rs allows CI to distinguish integration tests from unit tests efficiently.
Can I run e2e tests without Docker?
No. The local e2e suite depends on docker/docker-compose.local-e2e.yml for Postgres, Kafka, and S3 services. The xtask-local binary expects these containers to be available and will fail if the Docker environment is not running.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →