Mutators¶
go-mutesting ships with a full set of built-in mutation operators, organised by category.
Arithmetic¶
arithmetic/base¶
Swaps binary arithmetic operators.
| Original | Mutated |
|---|---|
+ |
- |
- |
+ |
* |
/ |
/ |
* |
% |
* |
arithmetic/bitwise¶
Swaps bitwise operators.
| Original | Mutated |
|---|---|
& |
\| |
\| |
& |
^ |
& |
&^ |
& |
>> |
<< |
<< |
>> |
arithmetic/assign_invert¶
Inverts compound assignment operators. Multiplication assignments (*=) whose right-hand side is constant zero are skipped to avoid division by zero compile errors.
| Original | Mutated |
|---|---|
+= |
-= |
-= |
+= |
*= |
/= |
/= |
*= |
%= |
*= |
&= |
\|= |
\|= |
&= |
^= |
&= |
<<= |
>>= |
>>= |
<<= |
&^= |
&= |
arithmetic/assignment¶
Strips compound assignment operators, replacing them with plain =. Shift assignments (<<=, >>=) whose right-hand side is not assignable to the left-hand side, or whose untyped constant value overflows the left-hand side type, are skipped to avoid uncompilable mutants.
| Original | Mutated |
|---|---|
+= |
= |
-= |
= |
*= |
= |
| … | = |
arithmetic/negate¶
Inverts unary minus expressions. Catches code that relies on a sign flip that tests don't verify. Signed integer minimum boundary constants (where positive inversion produces integer constant overflow) are skipped to avoid uncompilable mutants.
| Original | Mutated |
|---|---|
-x |
+x |
Loop¶
loop/break¶
Swaps break and continue inside loops.
loop/condition¶
Replaces loop conditions with 1 < 1 (always false), causing the loop body to never execute.
loop/range_break¶
Inserts a break at the start of each range loop body, causing only the first iteration to run.
Numbers¶
numbers/incrementer¶
Increments integer and float literals by 1. Maximum boundary literals for bounded integer types, any literal equal to math.MaxInt64 (typed or untyped), and minimum signed-integer boundary constants under unary minus (e.g. int8(-128)), are skipped where incrementing would overflow, to avoid uncompilable mutants.
numbers/decrementer¶
Decrements integer and float literals by 1. Zero literals in unsigned integer contexts and non-negative constant contexts (indexes, slice bounds, array lengths, and shift counts) are skipped where decrementing would produce uncompilable mutants.
numbers/float-negate¶
Replaces a float literal with its negation.
| Original | Mutated |
|---|---|
3.14 |
-3.14 |
Composite¶
composite/field-clear¶
Drops one keyed field from a composite literal (struct, map, or keyed array/slice literal), letting it fall back to its zero value. Targets fields set to a meaningful value that no test asserts — e.g. a config or options struct populated in full where only a couple of fields matter to the suite. Fields already at a zero value (0, "", false, nil), positional elements, and fields whose removal would leave a local variable or import unused are skipped.
| Original | Mutated |
|---|---|
Config{Timeout: 30, Retries: 3} |
Config{Retries: 3} |
Concurrency¶
concurrency/goroutine-remove¶
Removes the go keyword from goroutine launches, making concurrent calls synchronous. Kills tests that rely on goroutines running independently.
| Original | Mutated |
|---|---|
go f() |
f() |
Select¶
select/case-remove¶
Empties the body of each case branch in a select statement, one at a time.
select/default-remove¶
Empties the default branch of a select statement.
Conditional¶
conditional/negated¶
Negates comparison operators — > becomes <=, == becomes !=, etc. Catches off-by-one and inverted condition bugs.
conditional/bool-literal¶
Swaps true↔false in assignment right-hand sides and function call arguments. Finds hardcoded boolean values that tests never flip.
| Original | Mutated |
|---|---|
x = true |
x = false |
f(true) |
f(false) |
conditional/not¶
Removes the ! operator from negated conditions in if, for, and &&/|| expressions. Finds negations that tests never exercise the non-negated path of.
| Original | Mutated |
|---|---|
if !x { ... } |
if x { ... } |
Branch¶
branch/case¶
Empties case bodies in switch statements. When emptying a case would remove the enclosing function's terminating statement, the mutant keeps a zero-value return so it still compiles. Imported struct return types use the package name local to the source file, including aliases. Skips mutations that would leave an imported package unused.
branch/if¶
Empties the body of if and else if branches. When emptying the branch would remove the enclosing function's terminating statement, the mutant keeps a zero-value return so it still compiles. Imported struct return types use the package name local to the source file, including aliases. Skips mutations that would leave an imported package unused.
branch/else¶
Empties the body of else branches. When emptying the branch would remove the enclosing function's terminating statement, the mutant keeps a zero-value return so it still compiles. Imported struct return types use the package name local to the source file, including aliases. Skips mutations that would leave an imported package unused.
Expression¶
expression/comparison¶
Shifts comparison operators by one step — > becomes >=, >= becomes >. Catches off-by-one boundary errors.
expression/logical¶
Swaps && and || operators.
expression/remove¶
Makes each operand of && and || irrelevant by replacing it with true or false. Operands whose removal would leave a local variable or import unused are skipped to avoid uncompilable mutants.
expression/context-nil¶
Replaces context.Context arguments at call sites with nil. Arguments whose replacement would leave a local variable or imported package unused are skipped. Finds code paths that silently accept a nil context instead of propagating a real one.
| Original | Mutated |
|---|---|
f(ctx, x) |
f(nil, x) |
expression/error-guard¶
Replaces the condition of if err != nil / if err == nil guards with a boolean constant. Finds error-handling branches that tests never enter. Error guards whose condition is the only use of the error variable or import are skipped to avoid uncompilable mutants.
| Original | Mutated |
|---|---|
if err != nil |
if false |
if err == nil |
if true |
expression/errorf-wrap¶
Downgrades the error-wrapping verb in Errorf-style calls from %w to %v. The message is identical, but the returned error no longer wraps its cause, so errors.Is / errors.As stop matching. Finds error wrapping that no test ever unwraps.
| Original | Mutated |
|---|---|
fmt.Errorf("load: %w", err) |
fmt.Errorf("load: %v", err) |
expression/recover-clear¶
Neutralises a recover() call by rewriting it to func() any { return nil }(). The recovered value is always nil, so the recovery branch never runs and a panic propagates. Finds deferred recovery blocks that no test exercises.
| Original | Mutated |
|---|---|
if r := recover(); r != nil |
if r := func() any { return nil }(); r != nil |
expression/string-literal¶
Replaces non-empty string literals in == and != comparisons with "". Finds code that compares against a specific string value that tests never assert on.
| Original | Mutated |
|---|---|
s == "expected" |
s == "" |
Statement¶
statement/remove¶
Removes assignment, increment, decrement, and expression statements. Skips mutations that would leave an imported package unused.
statement/remove-self-assign¶
Removes self-assignment statements (a = a). These are typically dead code; this mutator confirms tests don't accidentally rely on them.
statement/return¶
Replaces each return value with the zero value for its type (false for bool, 0 for int, "" for string, nil for pointers and interfaces). Uses go/types for type resolution and preserves the package name local to the source file, including aliases, for imported struct types. When zeroing a return value whose only use was a local variable, emits a preceding _ = x assignment to keep the variable used and ensure the mutant compiles. Skips mutations that would leave an imported package unused. Finds functions whose return values tests never validate.
statement/defer-remove¶
Removes the defer keyword, turning deferred calls into immediate calls. Tests whether the timing of cleanup matters — e.g. mutex unlocks and file closes that must happen after the function body, not during it.
| Original | Mutated |
|---|---|
defer f() |
f() |
Disabling mutators¶
Use --disable <name> to turn off a specific mutator:
Use --list-mutators to list all registered mutator names.