Principle:MaterializeInc Materialize Local Test Execution
| Knowledge Sources | misc/python/materialize/cli/mzcompose.py
|
|---|---|
| Domains | Integration Testing, CLI Tooling, Developer Experience |
| Last Updated | 2026-02-08 |
Overview
CLI-driven test execution runs integration tests through a command-line interface that manages environment setup, Docker orchestration, and workflow dispatch behind simple commands.
Description
The Local Test Execution principle defines how developers and CI systems invoke integration tests through the mzcompose command-line tool. The tool wraps Docker Compose with Materialize-specific extensions, providing a unified interface for building images, starting services, running workflows, and tearing down environments.
The core insight is that integration tests in a complex distributed system involve substantial ceremony: building Docker images from source, resolving image dependencies, setting up networking, managing port allocation, and coordinating service lifecycles. The mzcompose CLI abstracts this complexity behind a familiar command structure modeled after Docker Compose itself.
The key command for test execution is mzcompose run <workflow>, which:
- Loads the
mzcompose.pyfile from the specified directory. - Resolves all image dependencies (building from source or pulling pre-built images).
- Detects whether the argument is a Docker Compose service or a custom workflow function.
- If it is a workflow, wraps the execution in a test case for analytics and JUnit reporting.
- Passes any extra arguments through to the workflow's
WorkflowArgumentParser. - Generates a JUnit XML report if running in CI.
- Reports success or failure based on the test results.
The CLI also provides system-level safety checks: it validates minimum memory and CPU requirements, supports --find for locating composition files in different directories, --preserve-ports for stable port mapping, and --sanity-restart-mz for post-test Materialized restart verification.
Usage
Use this principle when:
- Running integration tests locally during development.
- Understanding how CI invokes integration tests (the CI plugins call
mzcompose run). - Debugging test failures by reproducing the exact command that CI ran.
- Adding new workflow functions and verifying they are discoverable by the CLI.
Theoretical Basis
The principle is grounded in the facade pattern from software design: a simple interface that hides the complexity of a subsystem. The mzcompose CLI serves as a facade over:
- Docker Compose: The underlying container orchestration engine. Most
mzcomposecommands (up, down, logs, ps, etc.) delegate directly todocker compose. - mzbuild: Materialize's build system for Docker images, which resolves a dependency graph of images and builds them from source or pulls pre-built versions.
- Workflow dispatch: The mechanism that discovers
workflow_*functions inmzcompose.pyfiles and invokes them with the appropriateCompositionobject. - Test analytics: JUnit report generation and test result tracking for CI integration.
The command pattern is used for the CLI subcommands: each command (Run, Build, Down, etc.) is a class that implements a handle_composition method, allowing the command dispatch to be extensible without modifying the main parser.
The RunCommand.handle_composition() method implements smart dispatch: if the argument is a known workflow name, it runs the workflow; otherwise, it treats the argument as a Docker Compose service and delegates to docker compose run. This dual-mode behavior means developers do not need to learn a separate command syntax for workflows versus services.
The test wrapper pattern ensures that every workflow execution is wrapped in a test_case context manager, which records timing and success/failure status. This provides basic test analytics even for workflows that do not define their own fine-grained test cases.