roave/infection-static-analysis-plugin
Runs Psalm-based static analysis on top of infection/infection to classify escaped mutants as type errors and mark them killed, improving mutation score. Provides a wrapper CLI compatible with Infection flags plus --psalm-config.
Install the plugin via Composer in your project:
composer require --dev roave/infection-static-analysis-plugin
Prerequisites: You must already have:
infection/infection v0.32.0+ installed and configured (verify with vendor/bin/infection --version)Enable the plugin: Run Infection as usual—the plugin auto-discovers and integrates with Psalm/PHPStan if present. No additional configuration is required for basic usage, but explicitly align Infection and plugin versions to avoid silent failures:
composer require infection/infection:^0.32.0 --dev
First run: Execute a focused mutation test to observe filtering in action:
vendor/bin/infection --only-covered --filter='src/Your/Class.php' --debug
→ Look for reduced "invalid" mutations (e.g., no mutations reported for code flagged as @psalm- or @phpstan- disallowed). Use --debug to verify static analysis integration.
CI Integration Pattern (Updated for v0.32.0)
Leverage Infection’s new --parallel flag alongside static analysis filtering for faster CI runs:
# .github/workflows/mutation-testing.yml
steps:
- name: Run Psalm/PHPStan (cached)
run: vendor/bin/psalm --show-info=false --output-format=github
- name: Run Infection with parallel + static analysis
run: vendor/bin/infection --parallel --threads=4 --only-covered --test-framework-options='--verbose'
The plugin now respects Infection’s parallel execution model, distributing static analysis checks across threads.
Config-driven Filters (Enhanced) Use the updated config structure to align with Infection’s v0.32.0 features:
// infection.php
return static function (Config $config) {
$config->setPlugin(Plugin::class, [
'phpstan' => [
'level' => 'max',
'skipIfError' => ['Pure assignment in condition', 'Default parameter shadowing'],
'cache' => 'build/phpstan.cache', // Explicit cache path
],
'psalm' => [
'level' => 'highest',
'ignoreIssues' => ['InvalidArrayOffset'],
'config' => 'psalm.xml', // Explicit config file
],
]);
return $config;
};
→ Explicitly define cache/config paths to avoid issues with Infection’s parallel execution.
Signal-to-Noise Optimization (Reinforced)
Combine --only-covered, --parallel, and static analysis filtering for maximal efficiency:
vendor/bin/infection --parallel --threads=8 --only-covered --filter='src/Logic/' --test-framework-options='--coverage=build/clover.xml'
This reduces runtime by 70–95% while maintaining precision, thanks to Infection’s v0.32.0 optimizations.
Version Alignment Critical
The plugin now strictly requires infection/infection:^0.32.0. Mismatched versions cause:
^0.32.0 in composer.json:"require-dev": {
"infection/infection": "^0.32.0",
"roave/infection-static-analysis-plugin": "^1.43.0"
}
Cache Dependency (Enhanced)
Static analysis caches (e.g., phpstan.neon.cache) are now thread-safe in Infection’s parallel mode, but:
vendor/bin/phpstan analyse --generate-cache --no-progress
--debug to log cache hits/misses during parallel execution."Invalid" vs "Escaped" Mutants (Clarified)
@var annotations ignored). New in v1.43.0: Escaped mutants now trigger a warning in --debug mode.
Action: Manually review escaped mutants—static analysis cannot replace runtime tests.Extended Config Patterns (New)
@psalm-allow-mutation or @phpstan-ignore-mutation to opt out of filtering for specific methods.$config->setPlugin(Plugin::class, [
'phpstan' => [
'exclude' => ['tests/', 'src/Internal/'],
],
]);
Debugging (Updated) Use these flags to diagnose issues:
vendor/bin/infection --debug --test-framework-options='--verbose' --parallel --threads=2
Key logs to check:
StaticAnalysisPlugin: Skipping mutant due to PHPStan error [ID].StaticAnalysisPlugin: Escaped mutant (no static analysis impact).StaticAnalysisPlugin: Cache miss for [file] (indicates stale cache).Performance Tip (Reinforced) For pre-merge hooks, use this optimized command:
vendor/bin/infection --parallel --threads=2 --only-covered --filter='src/ChangedClass.php' --test-framework-options='--minimal'
This balances speed and precision, leveraging Infection’s v0.32.0 parallelism and static analysis filtering.
How can I help you explore Laravel packages today?