- 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
How-to Guides
How to run Infection only for changed files
If you have thousands of files and too many tests, running Mutation Testing can take hours for your project. In this case, it’s very convenient to run it only for the modified files.
Assuming you are on a feature branch, and the main branch is master
, we can do it as the following:
By using --git-diff-filter
option
This option allows filtering files for mutation by using git diff
under the hood.
If we want to mutate only A
dded and M
odified files, use:
infection --git-diff-filter=AM |
Read more about
--git-diff-filter
By using --git-diff-lines
option
This allows mutating only touched lines of code.
Useful to check how your changes impacts MSI in a feature branch. Useful for those who do not want / can’t write tests for the whole touched legacy file, but wants to cover their own changes (only modified lines).
infection --git-diff-lines |
Read more about
--git-diff-lines
By using --filter
option (for the old Infection versions)
CHANGED_FILES=$(git diff origin/master --diff-filter=AM --name-only | grep src/ | paste -sd "," -); |
The --diff-filter=AM
returns only added and modified files, because we are not going to use removed ones.
The --ignore-msi-with-no-mutations
option tells Infection to not error on min MSI when we have 0
mutations.
Example for Travis CI:
jobs: |
For each job, Travis CI fetches only tested branch:
git clone --depth=50 --branch=feature/branch |
That’s why we need to fetch $TRAVIS_BRANCH
as well to make a git diff
possible. Otherwise, you will get an error:
fatal: ambiguous argument 'origin/master': unknown revision or path not in the working tree. |
How to run Infection for functional tests
Imagine you have functional tests that do real SQL queries. Running such tests in parallel impossible without additional work, because 2 different concurrent processes will write to the same tables and conflict with each other.
To fix this issue, Infection provides TEST_TOKEN=<int>
environment variable for each process that can be used to set up different connections to the databases.
If you have 3 parallel processes, they will use db_1
, db_2
, db_3
correspondingly.
infection --threads=3 |
An example of how it can be done for Symfony project with Doctrine:
parameters: |
Or as a plain PHP code:
$dbName = sprintf('db_%s', getenv('TEST_TOKEN')); |
For this example to work, you will need to set up 3 database schemas.
How to disable Mutators and profiles
Disable Mutator
Mutators can be disabled in a config file - infection.json5
. Let’s say you don’t want to mutate +
to -
. In order to disable this Mutator, the following config can be used:
{ |
The full list of Mutator names can be found here.
In this example, we explicitly enable all Mutators from @default
profile and disable Plus
Mutator.
Read about Profiles here
Disable Profile
To disable all Mutators that work with Regular Expressions, we should disable the whole @regex
profile:
{ |
Disable in particular class or method or line
Sometimes you may want to disable Mutator or Profile just for one particular method or class. It’s possible with ignore
setting of Mutators and Profiles with the following syntax:
{ |
Want to ignore the whole class? App\Controller\User
All classes in the namespace: App\Api\*
All classes Product
in any namespace: App\*\Product
Method of the class: App\Api\Product::productList
Method in all classes: App\Api\*::productList
Method by pattern: App\Api\Product::pr?duc?List
Line of the code: App\Api\Product::product::33
Internally, all patterns are passed to fnmatch()
PHP function. Please read its documentation to better understand how it works.
Do not mutate the source code matched by regular expression
You may want to exclude mutations to the code that, if mutated, has little-to-no impact, or, alternatively, sometimes isn’t worth testing the result of - for example calls to a logging function.
If your codebase has lots of logging, this can generate many unwanted mutants and will greatly slow down the mutation test run.
Consider these examples:
- $this->logger->error($message, /* context */ ['user' => $user]); |
- Assert::numeric($string); |
To avoid them, you can ignore mutations by regular expression, matching the source code:
{ |
Or just per Mutator:
{ |
Exact matching:
{ |
Ignore any mutants with particular method name, e.g.:
- public function methodCall() { |
- $this->methodCall(); |
with the following config:
{ |
Do not add any delimiters (like /
) to the regular expression: we are adding and escaping them for you.
Disable by @infection-ignore-all
annotation
It’s possible to disable all mutations by adding @infection-ignore-all
annotation on class, method, and statement level.
/** |
See other examples here.
How to debug Infection
Sometimes you need to better understand what’s going on during execution of Infection.
- to use human-readable log file, use
text
logger - ininfection.json5
addlogs.text
key - information added to
text
log file is controlled by--log-verbosity
When --log-verbosity=all
is used, additionally killed and errored mutants will be added to the log file.
The verbosity of the log file,
all
- this mode will add“Killed mutants”
into log file and add additional information,default
- normal mode will skip“Killed mutants”
section in the log file,none
- which will disable logging to files.
Use the following config file
{ |
and execute Infection with
infection --log-verbosity=all |
If you want to also log PHPUnit’s output, as well as CLI commands that are executed internally by Infection, use --debug
infection --log-verbosity=all --debug |