← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Mutation Testing

testing PHP 7.1+ Advanced

Also Known As

mutation score Infection PHP mutant

TL;DR

A technique that automatically modifies source code and checks whether tests fail — surviving mutations indicate test gaps even where line coverage appears complete.

Explanation

A mutation testing tool makes small changes (mutations) to the source code — flipping a condition, changing an operator, removing a statement — then runs the test suite. If the tests still pass, the mutation 'survived', meaning no test catches that change. Mutation score = killed mutations / total mutations. A 90% line coverage suite with 40% mutation score has poor actual test quality. Infection is the PHP mutation testing framework.

Diagram

flowchart TD
    SRC[Source Code] --> MT[Mutation Tool<br/>Infection PHP]
    MT -->|Creates| M1[Mutant 1<br/>+ changed to -]
    MT -->|Creates| M2[Mutant 2<br/>if removed]
    MT -->|Creates| M3[Mutant 3<br/>true -> false]
    M1 & M2 & M3 --> SUITE[Test Suite]
    SUITE -->|Tests fail| KILLED[Mutant Killed<br/>good test]
    SUITE -->|Tests pass| SURVIVED[Mutant Survived<br/>test gap found]
style KILLED fill:#238636,color:#fff
style SURVIVED fill:#f85149,color:#fff

Common Misconception

100% code coverage means tests are thorough — mutation testing proves otherwise; covered code with no meaningful assertions produces surviving mutants.

Why It Matters

Mutation testing catches tests that assert nothing meaningful — they pass even when production code is wrong, providing false confidence in coverage metrics.

Common Mistakes

  • Running mutation testing on the full codebase at once — start with critical domain logic only; mutation testing is slow.
  • Targeting 100% mutation score — some mutations are equivalent (same behaviour, different code) and should be ignored.
  • Not interpreting surviving mutants carefully — some indicate test gaps, others are in unreachable code paths.
  • Using mutation testing instead of good test design — it is a diagnostic tool, not a substitute for thinking about what to test.

Code Examples

✗ Vulnerable
// Test with coverage but no real assertion:
public function testCalculate(): void {
    $calc = new Calculator();
    $result = $calc->add(2, 3); // Line executed — covered
    $this->assertTrue(true);   // No assertion on result — mutation survives!
    // Mutant: return $a - $b; — test still passes
}
✓ Fixed
// Meaningful assertion — kills the mutant:
public function testCalculate(): void {
    $calc = new Calculator();
    $this->assertSame(5, $calc->add(2, 3));
    $this->assertSame(-1, $calc->add(2, 3, subtract: true));
    // Mutant: return $a - $b; now fails the first assertion
}

Added 15 Mar 2026
Edited 19 Apr 2026
Views 28
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Perplexity 9 Amazonbot 5 Ahrefs 2 Google 2 Unknown AI 2 SEMrush 2 Majestic 1
crawler 22 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: High
⚡ Quick Fix
Run Infection PHP on your unit test suite — a mutant surviving means your test didn't detect a change in behaviour; fix by adding assertions that test the actual output
📦 Applies To
PHP 7.1+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
High line coverage with poor behaviour verification; tests that pass even when logic is deleted; assertions only checking return type not actual value
Auto-detectable: ✓ Yes infection phpunit pest
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update

✓ schema.org compliant