Naming Test Methods (Given/When/Then)
debt(d3/e1/b3/t5)
Closest to 'default linter catches the common case' (d3). The detection_hints list phpcs and eslint with a code_pattern for generic test names like test[A-Z] or test\d. These default linting tools can flag overly generic or poorly structured test method names automatically, making this a d3 rather than requiring specialist tools or manual review.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix is simply renaming the test method to follow the given/when/then pattern. Renaming a single method is a one-line change with no cross-cutting impact, as test names are local to the test class.
Closest to 'localised tax' (b3). Poor test naming affects the test suite and CI output readability, but the rest of the production codebase is unaffected. The burden is contained to the testing layer — future maintainers pay a tax when reading CI failures or navigating tests, but it doesn't shape architectural decisions.
Closest to 'notable trap' (t5). The misconception field states that developers think test names only matter for code readability, when in fact they are the primary signal in CI failure output. This is a documented gotcha that many developers eventually learn — they write generic names like testCalculate and only discover the problem when debugging CI failures in production, making it a t5 notable trap.
TL;DR
Explanation
Good test naming patterns: (1) Given/When/Then: givenExpiredToken_whenValidating_thenThrowsException. (2) Should: shouldThrowWhenTokenExpired. (3) Behaviour description: calculatesDiscountForPremiumUsers. Bad patterns: test1, testMethod, testCalculate. PHPUnit: method name is the test name in output. Use @test annotation or prefix test. Name should read as a specification — failing tests produce meaningful error messages. The name should say what the test verifies, not how. BDD frameworks (Behat, Pest) formalise this with descriptive strings.
Common Misconception
Why It Matters
Common Mistakes
- Using generic names: test1, testMethod, testSuccess.
- Naming after implementation: testCallsDiscountService instead of testAppliesDiscountForPremiumUsers.
- Not including the expected outcome in the name.
Code Examples
public function testCalculate(): void { }
public function testCalculate2(): void { }
public function testUserService(): void { }
// PHPUnit:
public function test_givenPremiumUser_whenCalculatingTotal_appliesDiscount(): void {}
public function test_givenExpiredCoupon_whenCheckingOut_throwsException(): void {}
// Pest:
it('applies discount for premium users', function() {});
it('throws when coupon is expired', function() {});