butcher 0.3.0
butcher: ^0.3.0 copied to clipboard
Mutation testing for Dart; rewrites the source into mutants and scores which ones the tests kill.
Changelog #
0.3.0 #
--test <path>, ortestsinbutcher.yaml, runs the named test files instead of every*_test.dart, so a bundled suite pays its startup once.--sandbox-scope=packagealso skips directories holding their ownpubspec.yamlthat no kept package reaches, such as nested workspace roots.
0.2.1 #
--sandbox-scope=packageno longer breaks a root pubspec whoseworkspace:list is followed by another key.
0.2.0 #
- Flutter packages: a package depending on the Flutter SDK runs its suites
with
flutter testand resolves withflutter pub get, using theflutterbeside the runningdartor underFLUTTER_ROOT. Covered mutants run the whole suite for now;--max-heap-mbis not supported for them yet. --filesmutates only the namedlib/files, and--diff-base <ref>only thelib/files changed since a git ref, uncommitted and untracked ones included. A scoped run records its scope under the report'sconfig.scope.butcher.logrecords each mutant as started before its suite runs, and an interrupted or aborted run prints the mutants still in flight, so a crashed run shows which mutants it was running.--max-heap-mbcaps the heap of every test process butcher starts. A mutant that exhausts it is reported asmemoryErrorinstead of taking the host down, and scores as neither killed nor survived.- A
coverage/lcov.infoolder than any file inlib/ortest/is skipped as stale and coverage is collected instead, so new lines are no longer reported as noCoverage. The console names the coverage source of every run. --sandbox-scope=packagecopies only the pub workspace members the selected package reaches into each sandbox, instead of the whole workspace. The default,workspace, is unchanged.
0.1.0 #
- First release. butcher is a fork of the MIT-licensed
radioactive_dartpackage by Ricardo Boss, taken with its full history, renamed, and split into a pub workspace; the upstream copyright notice travels with it. - The
butcherCLI mutateslib/, prints per-outcome counts, MSI and covered-code MSI, and writes a Stryker JSON report (--output). - Mutants are generated from the analyzer's AST: arithmetic, relational,
equality and logical operators, boolean literals, and nullability mutators
for
??,?.and injectednull. Identity replacements are rejected and promotion-breaking flips are skipped rather than reported. - Outcomes are killed, survived, noCoverage, timeout, unviable and runError.
Timeouts are inconclusive: they enter neither score, and a timeout rate is
printed whenever any occur. A run with no scoreable mutants reports no MSI
and fails
--threshold. - Mutants that fail static analysis report as unviable without a test run, so a compiler failure is never counted as a kill.
- Coverage routes each mutant to the test files that cover its line, cheapest
first, in one
--fail-fastrun. A project's owncoverage/lcov.infois picked up automatically,--coveragesupplies one, and otherwise coverage is collected in one extra suite run;--no-collect-coveragetreats all code as covered. - Each worker tests in its own sandbox, a temp-directory copy of the project holding what the repository's git listing names, so the project's own gitignore rules decide it. Selecting a pub workspace member copies the whole workspace while keeping tests, generation, coverage and report output rooted at that member.
excludein abutcher.yamlat the project root lists globs of files never mutated; generated sources such as.g.dartand.freezed.dartare skipped without it.- A red baseline aborts the run before generation; the green baseline's duration sets each mutant's deadline, so a slow selection is not a timeout.
--jobsclassifies in parallel, one sandbox per worker. A timed-out suite is killed with everything it spawned, and interrupting a run reaps every suite still in flight.--thresholdgates on the MSI and--max-timeoutson timed-out mutants. Exit codes are 0 success, 1 gate failed, 64 usage, 70 aborted run.- Wide-event CLEF logging: one tool log plus one log per sandbox, each
mutant's suite output kept as a capped excerpt;
--verboserenders the events on a terminal. All temp data lives under one root, redirectable withBUTCHER_TEMP, cleaned at the next run's startup under an exclusive lock. - Published to pub.dev on 2026-09-23.