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

Test Naming Conventions

Testing Beginner
debt(d7/e1/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints specify automated=no, and while phpunit/pest are listed as tools, they do not automatically flag poor naming conventions — no linter rule catches 'testGetUser()' as insufficiently descriptive. Only a human reviewer reading the test output or conducting a code review will notice the names are non-actionable.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix is purely a rename: change testGetUser() to test_it_returns_user_for_valid_id(). Each fix is a single identifier rename per test method, requiring no structural code changes.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Poor naming applies within the test suite only — the test files themselves carry the cost (harder to diagnose failures), but production code and other components are unaffected. It is a persistent readability tax on the test layer, but the rest of the codebase is not shaped by it.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception is explicit: developers naturally believe naming the method under test (testCalculateTotal) is sufficient. The trap is that the name describes implementation rather than scenario/behaviour, so a failing test gives zero diagnostic signal. This is a well-known testing gotcha that most developers encounter and learn over time, but it's not obvious to beginners.

About DEBT scoring →

Also Known As

test method naming BDD test names test description

TL;DR

Well-named tests read as specifications — they document what the system does, make failure messages self-explanatory, and allow filtering tests by feature or scenario.

Explanation

PHPUnit test methods should describe the scenario being tested, not the method under test. Pattern: testMethodName is poor (what scenario?); testUserCannotLoginWithWrongPassword is good (describes behaviour). BDD-style: it_rejects_login_with_wrong_password or givenActiveUser_whenWrongPassword_thenAccessDenied (Given/When/Then). The test name should make the failure message self-explanatory — if it fails you know exactly what broke without reading the test body.

Common Misconception

testMethodName() is a sufficient test name — it names the method under test, not the scenario; when the test fails, 'testCalculateTotal failed' tells you nothing about what went wrong.

Why It Matters

A failed test named testUserCannotPurchaseWithExpiredCreditCard is immediately actionable; a failed test named testCheckout requires reading the test body before you understand what broke.

Common Mistakes

  • test + method name: testGetUser() — what scenario? What input? What expected outcome?
  • Overly generic names: testHappyPath(), testEdgeCase() — not descriptive.
  • Not using @test annotation with natural language: /** @test */ public function user_cannot_login_with_wrong_password().
  • Names that describe implementation: testCallsDatabaseQueryOnce() — describe behaviour, not internals.

Code Examples

✗ Vulnerable
// Useless test names — failures are opaque:
public function testCalculate(): void { /* What calculation? What case? */ }
public function testUser(): void { /* What about a user? */ }
public function testHappyPath(): void { /* Every test is a happy path */ }
public function testGetUserById(): void { /* What scenario? Exists? Missing? */ }
✓ Fixed
// Self-documenting test names:
public function testCalculateTotalAppliesVatCorrectlyForUkCustomers(): void { }
public function testGuestUserCannotAccessAdminPanel(): void { }
public function testOrderStatusChangesToProcessingAfterPaymentConfirmed(): void { }
public function testFindByIdReturnsNullWhenUserDoesNotExist(): void { }

// Or BDD-style with @test:
/** @test */
public function it_rejects_checkout_when_cart_is_empty(): void { }

Added 16 Mar 2026
Edited 22 Mar 2026
Views 46
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 2 pings S 1 ping S 0 pings M 2 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Perplexity 7 Amazonbot 7 Google 7 Scrapy 5 Ahrefs 4 Unknown AI 3 SEMrush 3 ChatGPT 2 Claude 1 Meta AI 1 PetalBot 1
crawler 35 crawler_json 5 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Name tests as sentences: test_it_rejects_orders_above_credit_limit() or 'it rejects orders above credit limit' in Pest — the test name should be the failing assertion message
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
testSomething() generic test names; testMethod1() testMethod2(); test names that don't describe behaviour
Auto-detectable: ✗ No phpunit pest
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✗ Manual fix Fix: Low Context: File


✓ schema.org compliant