Regression Testing
debt(d7/e5/b5/t5)
Closest to 'only careful code review or runtime testing' (d7), missing regression tests aren't flagged by phpunit/pest themselves — you only notice when a bug returns or during code review of a bug fix PR without an accompanying test.
Closest to 'touches multiple files / significant refactor in one component' (e5), backfilling a regression suite means writing many tests across the codebase, not a one-line fix; per-bug the fix is small but establishing the practice is broader.
Closest to 'persistent productivity tax' (b5), the suite applies across web/cli/queue contexts and must be maintained on every commit; slow suites slow every workstream but don't define system shape.
Closest to 'notable trap' (t5), per misconception developers think regression testing is a separate phase rather than the cumulative effect of CI running all tests on every commit — a documented gotcha most devs learn.
Also Known As
TL;DR
Explanation
Regression testing encompasses all tests that verify known-good behaviour is preserved after a change. In CI/CD, the entire test suite is a regression suite — every commit runs all tests to catch regressions early. The cost of regression testing is proportional to test execution time, which is why the test pyramid (many fast unit tests, few slow E2E tests) optimises for fast regression feedback. Mutation testing extends regression testing by verifying that the tests themselves are meaningful.
Common Misconception
Why It Matters
Common Mistakes
- Not running regression tests on every commit — regressions compound when multiple unverified changes accumulate.
- Slow regression suite that developers skip locally — fast feedback loops require tests to run in minutes.
- Not adding a regression test when fixing a bug — without a test, the bug returns silently.
- Deleting tests that are 'in the way' of a refactor — they are protecting against regression.
Code Examples
// Bug fixed without adding a regression test:
// Report: calculate_discount() returns negative for items over $1000
// Fix applied — but no test added
// Next refactor: same bug reintroduced, silently
function calculate_discount(float $price): float {
return $price > 100 ? $price * 0.1 : 0; // Bug: should be $price - $price * 0.1
}
// Bug fixed WITH a regression test:
function testDiscountNeverExceedsPrice(): void {
$discount = calculate_discount(1500.00);
$this->assertGreaterThanOrEqual(0, 1500.00 - $discount); // Price never goes negative
$this->assertLessThanOrEqual(1500.00, $discount); // Discount never exceeds price
}