NAME
App::Test::Generator::Mutator - Generate and apply mutation tests
VERSION
Version 0.34
DESCRIPTION
App::Test::Generator::Mutator is a mutation engine that programmatically alters Perl source files to evaluate the effectiveness of a project's test suite. It analyses modules, generates systematic code mutations (such as conditional inversions, logical operator changes, and numeric boundary flips), and applies them within an isolated workspace so tests can be executed safely against each modified variant.
By tracking which mutants are killed (cause tests to fail) versus those that survive (tests still pass), the module enables calculation of a mutation score, providing a quantitative measure of how well the test suite detects unintended behavioural changes.
new
Construct a new Mutator for a given source file.
my $mutator = App::Test::Generator::Mutator->new(
file => 'lib/My/Module.pm',
lib_dir => 'lib',
mutation_level => 'full',
);
Arguments
filePath to the Perl source file to mutate. Required. Must exist on disk.
lib_dirRoot library directory. Optional — defaults to
lib.mutation_levelControls the breadth of mutation.
fullapplies all mutations;fastdeduplicates and removes redundant mutants first. Optional — defaults tofull.
Returns
A blessed hashref. Croaks if file is missing or does not exist.
API specification
input
{
file => { type => SCALAR },
lib_dir => { type => SCALAR, optional => 1 },
mutation_level => { type => SCALAR, optional => 1 },
}
output
{
type => OBJECT,
isa => 'App::Test::Generator::Mutator',
}
generate_mutants
Parse the target file and generate all mutants by running each registered mutation strategy against the PPI document.
my @mutants = $mutator->generate_mutants();
Arguments
None beyond $self.
Returns
A list of App::Test::Generator::Mutant objects. In fast mode, redundant and duplicate mutants are removed before returning.
API specification
input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Mutator' },
}
output
{
type => ARRAYREF,
elements => { type => OBJECT, isa => 'App::Test::Generator::Mutant' },
}
prepare_workspace
Prepare an isolated temporary workspace for a single mutation test run.
The entire lib_dir tree is copied into the workspace so that all module dependencies resolve correctly when the test suite runs against the mutant. Only after this copy is complete is the single target file overwritten by apply_mutant.
my $workspace = $mutator->prepare_workspace();
$mutator->apply_mutant($mutant);
local $ENV{PERL5LIB} = "$workspace/lib";
my $survived = (system('prove', 't') == 0);
Arguments
None beyond $self.
Returns
A string containing the absolute path to the temporary directory created. The directory is automatically removed when the object goes out of scope via File::Temp's CLEANUP => 1 behaviour.
Side effects
Creates a temporary directory. Recursively copies lib_dir into it. Sets $self->{workspace} and $self->{relative}.
Notes
Call prepare_workspace once per file, then apply_mutant once per mutant within that file. Do not store the returned path beyond the lifetime of the enclosing scope.
API specification
input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Mutator' },
}
output
{
type => SCALAR,
}
apply_mutant
Apply a single mutant's transform to the target file in the workspace.
$mutator->apply_mutant($mutant);
Arguments
$mutantAn App::Test::Generator::Mutant object whose
transformclosure will be applied to the workspace copy of the target file.
Returns
Nothing. Modifies the workspace copy of the target file in place.
Side effects
Overwrites the target file in the workspace with the mutated version.
API specification
input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Mutator' },
mutant => { type => OBJECT, isa => 'App::Test::Generator::Mutant' },
}
output
{ type => UNDEF }
run_tests
Run the test suite against the current workspace and return whether all tests passed.
my $survived = $mutator->run_tests();
Arguments
None beyond $self.
Returns
1 if all tests passed (mutant survived), 0 if any test failed (mutant killed).
Side effects
Executes an external process running the test suite.
Notes
Uses prove found on PATH. Sets PERL5LIB to include the workspace lib directory before running.
API specification
input
{
self => { type => OBJECT, isa => 'App::Test::Generator::Mutator' },
}
output
{ type => SCALAR }
SEE ALSO
bin/test-generator-mutate- Devel::Mutator
AUTHOR
Nigel Horne, <njh at nigelhorne.com>
Portions of this module's initial design and documentation were created with the assistance of AI.
LICENCE AND COPYRIGHT
Copyright 2026 Nigel Horne.
Usage is subject to the terms of GPL2. If you use it, please let me know.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 75:
Non-ASCII character seen before =encoding in '—'. Assuming UTF-8