Il mutation testing valuta la qualità di una suite di test introducendo deliberatamente piccoli bug ("mutanti") nel codice e verificando se i test li rilevano. Misura quanto i test siano realmente capaci di individuare i difetti, andando oltre la coverage, che misura soltanto l'esecuzione.
Come funziona il mutation testing
1. A tool makes small changes (MUTATIONS) to the code, e.g.:
→ change + to -, > to >=, true to false, remove a statement, change a constant
→ each mutation = a deliberate "bug" (a MUTANT version of the code)
2. Run the TEST SUITE against each mutant:
→ tests FAIL → the mutant is "KILLED" (good — tests caught the bug) ✓
→ tests PASS → the mutant "SURVIVED" (bad — tests DIDN'T catch the bug) ✗
3. MUTATION SCORE = % of mutants killed → measures how good the tests are at catching bugs
Perché è migliore della coverage
COVERAGE → measures if code was EXECUTED (not if behavior was verified) → can be high with
weak tests (no real assertions)
MUTATION TESTING → measures if tests actually DETECT bugs (changes in behavior):
→ a surviving mutant reveals a GAP — tests execute that code but don't verify it well
(weak/missing assertions, untested behavior)
→ A much stronger signal of TEST QUALITY than coverage.
Considerazioni
✓ Reveals weak tests (high coverage but surviving mutants = false confidence)
⚠️ COMPUTATIONALLY EXPENSIVE (runs the suite many times — once per mutant) → slow
⚠️ "Equivalent mutants" (mutations that don't change behavior) → false survivors to ignore
→ Tools: Stryker (JS), PIT (Java), mutmut (Python). Use on critical code; run periodically.
Perché è importante
Comprendere il mutation testing è una conoscenza preziosa di livello senior perché fornisce una misura della qualità dei test molto più solida della coverage, colmando il punto debole principale della coverage, ed è quindi utile per valutare e migliorare le suite di test.
L'intuizione fondamentale è che la coverage misura l'esecuzione, non la verifica: il codice può essere "coperto" (eseguito) da test che in realtà non ne verificano il comportamento (asserzioni deboli o assenti), dando una falsa sicurezza. Il mutation testing affronta questo problema misurando se i test rilevano davvero i bug: introduce piccoli bug deliberati (mutanti) nel codice e verifica se i test li individuano (un mutante "ucciso" da test che falliscono è positivo; un mutante "sopravvissuto" significa che i test non hanno rilevato quel bug).
Il mutation score (percentuale di mutanti uccisi) è un segnale di qualità dei test molto più forte della coverage perché rivela se i test verificano realmente il comportamento: un mutante sopravvissuto espone una lacuna reale (i test eseguono il codice ma non lo verificano bene, ad esempio asserzioni deboli o comportamenti non testati) che la coverage non coglierebbe.
Comprendere questo — che il mutation testing rivela test deboli nascosti dietro un'alta coverage — è il valore chiave, perché affronta il limite per cui un'alta coverage non garantisce buoni test.
Comprendere le considerazioni — che è computazionalmente costoso (esegue la suite una volta per mutante, rendendolo lento), che i "mutanti equivalenti" (mutazioni che non cambiano il comportamento) sono falsi sopravvissuti da ignorare, e che esistono strumenti appositi (Stryker, PIT, mutmut) — riflette una consapevolezza pratica di quando e come usarlo (su codice critico, periodicamente, anziché di continuo).
Dato che la qualità dei test conta davvero (la sola coverage può dare una falsa sicurezza) e che il mutation testing fornisce una misura molto più solida verificando se i test individuano realmente i bug, e dato che comprenderlo, il suo vantaggio rispetto alla coverage e le sue considerazioni pratiche è utile per valutare e migliorare davvero le suite di test, comprendere il mutation testing è una conoscenza preziosa di livello senior — una tecnica sofisticata per misurare la reale qualità dei test, che affronta il punto debole principale della coverage e riflette la comprensione più profonda dell'efficacia dei test attesa per i ruoli senior interessati alla genuina qualità dei test, non solo ai numeri della coverage.
