Skip to content

Configuration

mutato init creates a .mutato/ folder next to your solution holding the config (config.toml) and a .gitignore that keeps report output out of your repo — reports land in .mutato/reports/ by default. Config keys mirror the CLI flag names; any CLI flag overrides the matching config value, and relative paths resolve against the folder holding .mutato/.

project = "src/Polly.Core/Polly.Core.csproj"
tests-project = "test/Polly.Core.Tests/Polly.Core.Tests.csproj"
filter = "Polly.Retry.RetryHelper" # type / namespace prefix to mutate
workers = 4
timeout = 10 # per-mutant timeout, seconds
json = ".mutato/reports/report.json"
html = ".mutato/reports/report.html"
[thresholds] # displayed today; exit-code gating is on the roadmap
high = 80
break = 60

A legacy ./mutation-config.json (the pre-.mutato shape) still loads when no config.toml exists, and mutato init migrates it. --config <file> points at either format, by extension.

Flag Purpose
--project <csproj> The project to mutate (code under test).
--tests-project <csproj> The test project to build and run.
--tests <dll> Use a prebuilt test assembly and skip the build.
--filter <prefix> Restrict mutation to a type or namespace prefix.
--test-class <fqn> Run only one test class (handy to dodge flaky baselines).
--workers <n> Number of warm worker hosts.
--timeout <seconds> Per-mutant timeout ceiling.
--json <path> Write a Stryker-schema JSON report.
--html <path> Write an HTML report.
--config <file> Read a specific config file.

Start with a narrow --filter on a single type; widen it once the baseline is green and the score looks sane.

For TUnit suites, --host tunit-direct drives the source-generated test delegates directly and skips the per-run Microsoft Testing Platform pipeline (~85 ms/run → sub-millisecond), behind the same warm-pool, coverage, and timeout machinery.

It’s a large win on fast unit suites and a smaller one on slow or async suites where test time dominates. It handles parameterless and [Arguments] tests plus any TUnit data source — [MethodDataSource] and custom generators are expanded through TUnit’s own GetDataRowsAsync. For anything it can’t host faithfully (constructor/property injection, lifecycle hooks) it falls back to the MTP host for that run, so verdicts are never wrong.