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 test for Rust back-end tests
  • vitest for 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 via xtask-local with Docker Compose infrastructure.
  • Safety guards in tooling/seed_cli/src/entity/scenario/mod.rs prevent 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →