Runs tests and outputs results as JSON.
This task wraps mix test and configures ExUnit to use
ExUnitJSON.Formatter for JSON output instead of the default
CLI formatter.
Setup
Add this to your project's mix.exs to ensure test.json runs in the test environment:
def cli do
[preferred_envs: ["test.json": :test]]
endThis is required because Mix doesn't inherit preferred_envs from dependencies.
Usage
mix test.json
mix test.json test/my_test.exs
mix test.json test/my_test.exs:42Options
All standard mix test options are supported, plus:
--summary-only- Output only the summary, omit individual test results--all- Output all tests (default shows only failures)--failures-only- Output only failed tests (DEFAULT - AI-optimized)--first-failure- Output only the first failed test (quick iteration)--filter-out PATTERN- Mark failures matching pattern as filtered (can repeat)--output FILE- Write JSON to file instead of stdout--compact- JSONL output with minimal fields (one line per test)--group-by-error- Group failures by similar error message--quiet- Suppress Logger output and TIP warnings for clean JSON piping--no-warn- Suppress the "use --failed" warning when previous failures exist--cover- Enable code coverage (off by default for faster runs)--cover-threshold N- Fail if overall coverage is below N (0-100). Requires--cover
Coverage
Coverage is disabled by default for faster test runs. Use --cover to enable:
mix test.json --coverThe JSON output includes a coverage key with:
"coverage": {
"total_percentage": 96.96,
"total_lines": 330,
"covered_lines": 320,
"threshold": 80,
"threshold_met": true,
"modules": [
{
"module": "MyApp.Module",
"file": "lib/my_app/module.ex",
"percentage": 92.68,
"covered_lines": 38,
"uncovered_lines": [45, 67, 89]
}
]
}Default Behavior (v0.3.0+)
By default, mix test.json outputs only failed tests (equivalent to --failures-only).
This is optimized for AI agents where passing tests are noise.
Use --all to include all tests in output when needed.
Flag Precedence
When multiple filtering flags are combined, they follow this priority:
--summary-only- Highest priority, omits tests array entirely--first-failure- Returns only the first failed test--failures-only/--all- Filter to failures or show all tests
For example, --summary-only --all will omit the tests array.
Iteration Workflow
When previous test failures exist, a tip is shown suggesting
to use --failed for faster iteration:
TIP: 3 previous failure(s) exist. Consider:
mix test.json --failedThis warning is skipped when:
--failedis already used- A specific file or directory is targeted
--onlyor--excludetag filters are used--no-warnflag is passed
Strict Enforcement
To block full test runs when failures exist (useful for AI-assisted workflows):
# config/test.exs
config :ex_unit_json, enforce_failed: trueThis will exit with an error instead of just warning.
Examples
# Run all tests with JSON output
mix test.json
# Run specific file
mix test.json test/my_test.exs
# Output only failures to a file
mix test.json --failures-only --output failures.json