- Guide
- Playground
- GitHub
-
Ecosystem
Help
Resource Lists
Documentation
- Introduction
- Installation
- Usage
- Command Line Options
- Mutators
- Custom Mutators
- Profiles
- Using with CI
- Mutation Badge, cloud HTML report
- How-to Guides
- Caveats
- Debugging Issues
- Infection Playground
- GitHub Sponsors ♥️
- Supported Test Frameworks
Miscellaneous
- Compare with competitors
Posts
- What's new in Infection 0.26.0
- What's new in Infection 0.25.0
- What's new in Infection 0.24.0
- What's new in Infection 0.23.0
- What's new in Infection 0.21.0
Usage
Configuration
The first time you run Infection for your project, it will ask you several questions to create a config file infection.json5, with the following structure:
{ |
If you want to override settings locally, create and commit to VCS infection.json5.dist but locally use infection.json5 which should be ignored (e.g. in .gitignore).
By default, Infection uses
json5format for configuration file. It allows using comments, ES5-like keys and many more. But if you for some reason can’t use it, Infection also supportsjsonformat.
Configuration settings
sourcesection:directories- array, contains all folders with source code you want to mutate. Can be., but make sure to excludevendorin this case.excludes- array, contains all folders or files you want to exclude within your source folders. It accepts full paths, as well as regular expressions, enclosed by any delimiter accepted by PHP. It accepts glob pattern too. However, its usage is discouraged, as it does not work exactly the same in all OS.
Infection automatically excludesvendor,test,testsfolders if the source folder is.(current dir). Make sure to not mutate your test suite.
Paths underexcludeskey are relative to thesource.directoriesfolders.
Here are some examples ofexcludes, assuming thatsrcis defined insource.directories:"excludes": ["Config"]skips the foldersrc/Config."excludes": ["Folder/with/File.php"]skips the filesrc/Folder/with/File.php."excludes": ["/\\.interface\\.php/"]skips all files containing.interface.phpin the name."excludes": ["{Infrastructure/.*}"]skips all files withinsrc/Infrastructurefolder. Note that braces ({}) is a valid regex delimiter in PHP."excludes": ["{.*/Infrastructure/.*}"]skips all files within theInfrastructurepath of the second level of directories withinsrc. Therefore,src/Shared/Infrastructureorsrc/SomeBoundedContext/Infrastructurewould be excluded, whereassrc/Shared/Domainorsrc/SomeBoundedContext/Applicationwould not.
timeout- the maximum allowed time for mutated processes to run, in whole seconds, before they are considered a timeout. Make sure to set it to higher value than your tests are executed in seconds to avoid false-positives.threads- the number of threads to use by the runner when executing the mutations. Use “max” to auto calculate it.logstext- human-readable text log file. Must see to understand what is going on during mutation process.html- human-readable report, similar to PHPUnit HTML report. Based on Stryker Elements. Here is an example for Infection itself. If you want to store HTML report in the cloud (useful for OSS projects), see Stryker Dashboard integration.summary- summary log file, which will only display the amount of mutants per category, (Killed, Errored, Escaped, Timed Out, Skipped, and Not Covered)json- machine-readable file in JSON format. Can be programmatically analyzed. In addition to general stats, contains original, mutated code, diff and test framework output for each Mutant.perMutator- a markdown file which will give a break-down of the effectiveness of each mutator.
Each of the above logs accept a local filename to write to (eginfection.log), or you can write to the terminal usingphp://stdoutorphp://stderr, this can be useful in CI to store the mutation results in the output.github- prints GitHub Annotation warnings right in the Pull Request. Supposed to be used with GitHub Actions. See--logger-github, but usually not necessary as it is automatically detected.gitlab- GitLab (Code Climate) code quality report. Can be processed as acodequalityreport artifact in Gitlab.summaryJson- machine-readable file in JSON format likejsonbut containing only general stats. Can be programmatically analyzed, for example on CI.
tmpDir- Optional. It’s a folder where Infection creates its configs, caches and other stuff. It may be useful for people who doesn’t have access to the default system temporary folder and/or doesn’t have write permissions. Either absolute/tmp/folderor relativevar/cachepaths can be used.phpUnit- optional keyconfigDir- custom directory path withphpunit.xml.distfile. This is useful for example for old Symfony app, wherephpunit.xml.distis located at./appcustomPath- custom path to PHPUnit executable. This is useful when you run tests by external shared phar file that is located outside project root.
ignoreMsiWithNoMutations- optional key, whether to ignore MSI violations with zero mutationsminMsi- optional key, a value for the Minimum Mutation Score Indicator (MSI) percentage valueminCoveredMsi- optional key, a value for the Minimum Covered Code Mutation Score Indicator (MSI) percentage valuemutators: optional key, it contains the settings for different mutations and profiles, read more about it heretestFramework: optional key, it sets the framework to use for testing. Defaults tophpunit. This gets overridden by the--test-frameworkcommand line argument.testFrameworkOptions: optional key, specify additional options to pass to the test framework (IE: Enabling Verbose Mode).--test-framework-optionswill override this option.staticAnalysisTool: optional key, it sets the Static Analysis tool to use to catch escaped MutantsstaticAnalysisToolOptionsoptional key, it specifies additional options to pass to the static analysis tool (e.g. memory limit).--static-analysis-tool-optionswill override this option.bootstrap: optional key, use it to specify a file to include as part of the startup to pre-configure the Infection environment. Useful for adding custom autoloaders not included in composer.initialTestsPhpOptions: optional key, specify additional php options for the initial test (IE: Enabling X-Debug).--initial-tests-php-optionswill override this option.
How to use custom autoloader or bootstrap file
If you have a custom autoloader or bootstrap file for your application, you should tell Infection about it.
For example, you have
// custom-autoloader.php |
then you have to add it to the infection.json5 file:
{ |
Thus, Infection will know how to autoload NonPsr4CompliantFile class. Without adding it to the config, Infection will not be able to create Mutations because internally it uses new \ReflectionClass() objects.
Running Infection
Ensure that your tests are all in a passing state (incomplete and skipped tests are allowed). Infection will quit if any of your tests are failing.
If you have installed Infection as a global composer package, just run it in your project’s root:
infection |
or if you cloned it to some folder:
# cd /path/to/project/root |
Running with Xdebug
In order to run Infection with Xdebug, you have several options:
Enable Xdebug globally
In this case just run
./infection.phar --threads=4 |
Enable Xdebug per process
Since Infection needs Xdebug only to generate code coverage in a separate process, it is possible to enable debugger just there.
Assuming Xdebug is disabled globally, run
./infection.phar --initial-tests-php-options="-d zend_extension=xdebug.so" |
Running with phpdbg
In order to run Infection with phpdbg instead of Xdebug, you need to execute the following command:
phpdbg -qrr infection.phar |
Running without debugger
It is possible to run Infection without any debugger enabled. However, in this case you should provide already generated code coverage as an option
./infection.phar --coverage=path/to/coverage |
Read more what types of coverage Infection requires and how to do it.
@infection-ignore-all support
Infection supports @infection-ignore-all annotation on class, method, and statement level.
The following class will not be mutated even though it might have few covered lines.
/** |
In this example, method generate() will be skipped from mutation logic, but getDependencies() will be mutated as usual method.
class ProductFixture |
Likewise, given this annotation Infection won’t consider anything in this loop:
/** @infection-ignore-all */ |
Exposed environment variables
Infection exposes a couple of environment variables:
INFECTION=1this can be used in test environment to check whether the tests are executed from Infection or not.TEST_TOKEN=<int>for each process that Infection creates for running tests for particular Mutant, it addsTEST_TOKEN=<int>environment variable to be used for setting up connections to different databases. Read more here.