Basic Usage
Run all discovered merits in the current directory:Filtering Tests
By Keyword Expression
Use-k to filter tests by name with boolean expressions:
-k agent matches merit_agent_response, merit_weather_agent, etc.
By Tags
Use-t/--tag to include tests with specific tags:
--skip-tag to exclude tests:
Controlling Execution
Stop on Failure
--maxfail N - Stop after N failures:
--fail-fast - Stop at the first failed assertion within a test:
--fail-fast, Merit collects all assertion failures in a test. With it, the test stops at the first failure.
Concurrency
Control parallel test execution with--concurrency:
- Sequential (1): Default. Predictable output, easier debugging.
- Concurrent (>1): Faster runs for independent tests. Use with stateless SUTs.
- Unlimited (0): Maximum parallelism for large test suites.
def merit_*), Merit runs test bodies in worker threads by default to keep the event loop responsive. Use @merit.run_inline on a sync merit when it must run on the main event-loop thread.
Timeout
Set a global timeout for the entire test run:Verbosity
Control output detail with-v (verbose) or -q (quiet):
-qqor lower: Only failed/errored tests shown-q: Less output- Default (0): Standard output
-v,-vv: More detail
Output Capture
By default, Merit captures stdout and stderr during test execution. Use-s to show output live:
Tracing
Enable OpenTelemetry tracing to capture spans from your SUT and tests:- Asserting tool calls in agent tests
- Debugging LLM request/response flows
- Performance analysis
Custom Run UUID
By default, Merit generates a run UUID automatically. You can provide one explicitly when you need a stable external correlation ID (for example, linking CI jobs to Merit runs).CLI
Provide a UUID with--run-id:
2
and no tests are executed.
Python API
You can set a default run UUID on the runner, and override it perrun() call:
--run-id or Python API parameters. They are not
read from pyproject.toml, merit.toml, or environment variables.
If save_to_db=True and the selected run UUID already exists, Runner.run() raises
ValueError.
Configuration Files
Define default options inpyproject.toml or merit.toml:
pyproject.toml:
Understanding Test Output
Merit reports test status as tests complete with a compact line per file by default:-v to show per-test lines with durations and detailed sub-results.
Status symbols:
✓(green): PASSED - Test succeeded✗(red): FAILED - Assertion failed!(yellow): ERROR - Unexpected exception-(yellow): SKIPPED - Test was skippedx(blue): XFAILED - Expected failure occurred!(magenta): XPASSED - Expected failure passed (usually bad)
0: All tests passed (or only skipped/xfailed)1: At least one test failed or errored2: Invalid CLI usage or configuration error (including duplicate--run-id)
Repeated Tests
For tests with@merit.repeat(), verbose output shows aggregated results:
execution.sub_executions.
Reporter System
Merit uses an async reporter architecture for flexible output handling.The Reporter Interface
All reporters implement theReporter ABC from src/merit/reports/base.py:
Built-in Reporters
ConsoleReporter (default): Outputs to terminal with Rich formatting.Creating Custom Reporters
Create custom reporters by subclassingReporter and implementing all abstract methods.
Override on_test_start if you need live in-flight state:
Using Multiple Reporters
Use multiple reporters simultaneously with the programmatic API:ConsoleReporter is built-in. Create custom reporters for JSON, HTML, database, or external service integration.
Examples
Run smoke tests concurrently:Database Persistence
Merit automatically persists test run data to a SQLite database for historical tracking and analysis.Database Location
By default, Merit stores the database at the project root:pyproject.toml.
Disabling Database Persistence
To disable database writes (e.g., for CI environments or quick local runs):Custom Database Path
Specify a custom database location:pyproject.toml:
Database Management Commands
Merit provides CLI commands to manage the database:Check Database Status
View current schema version and pending migrations:Run Migrations
Apply pending schema migrations:Backup Database
Create a timestamped backup:.merit/merit.db.backup.YYYYMMDD_HHMMSS
Reset Database
Delete and recreate the database (destructive):--yes, Merit prints a warning and exits without resetting the database.
What’s Stored
The database stores:- Test run metadata (timestamp, environment, git info)
- Individual test executions and results
- Assertion results and predicate outcomes
- Metric results and statistical data
- Trace references (if tracing enabled)
- Error tracebacks for failed tests
Database Schema
The schema is versioned and managed through migrations. Current tables include:runs- Test run sessionstest_executions- Individual test resultsmetrics- Aggregated metricsassertions- Assertion outcomespredicates- Predicate results linked to assertionstrace_spans- Trace spans linked to executions
PRAGMA user_version (shown by merit db status as “Current version”).
Writing Merits
Learn how to write merit functions and use decorators
Merit Concept
Deep dive into discovery, parametrization, and execution