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

Unit Testing

Testing PHP 5.0+ Beginner
debt(d7/e5/b5/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). Tools like phpunit, pest, phpstan, and infection can flag absence of a test directory or low coverage (<40%), but they cannot reliably detect tests that hit real databases/filesystem/network, tests with no assertions, or tests tightly coupled to implementation — these require careful code review. Coverage thresholds are blunt instruments and won't catch false-confidence tests that always pass.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix describes injecting all dependencies so they can be mocked, applying arrange-act-assert pattern, and testing one unit of behaviour per test. Retrofitting a codebase that has no isolation, hits real databases, or has tightly coupled tests requires touching many test files and often refactoring production code to enable dependency injection — more than a single-line fix but typically contained within the testing layer and affected components.

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

Closest to 'persistent productivity tax' (b5). Unit testing applies across web, cli, and queue-worker contexts (broad applies_to). A codebase with poor or absent unit tests creates a persistent productivity tax: every refactor carries regression risk, onboarding is slower, and CI pipelines give false confidence. However, it doesn't define the system's architectural shape the way a database choice would — it's a sustained drag rather than a gravitational centre.

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

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field directly identifies the canonical trap: developers believe a unit test tests a single function/method, when the defining characteristic is actually speed and isolation from external dependencies. Common mistakes compound this — tests with no assertions, tests coupled to implementation details, missing edge cases. These are well-documented gotchas that most developers eventually encounter and correct, fitting t5.

About DEBT scoring →

Also Known As

unit tests PHPUnit isolated testing

TL;DR

Automated tests that verify individual units of code (classes, methods) in isolation from external dependencies.

Explanation

Unit tests isolate a single class or function, replacing real dependencies (databases, HTTP clients, file systems) with test doubles (mocks, stubs, fakes). They run fast (no I/O), pinpoint failures precisely, and are the foundation of test-driven development. PHPUnit is the standard PHP unit testing framework. Well-designed code (injected dependencies, small classes) is easy to unit test — if a class is hard to test, that's a signal its design needs improvement. Aim for high coverage of business logic, edge cases, and error paths.

Common Misconception

A unit test tests a single function or method in isolation. A unit is the smallest testable piece of behaviour — which may span multiple methods. The defining characteristic is speed and isolation from external dependencies, not strict single-method scope.

Why It Matters

Unit tests verify individual functions and methods in isolation — they run in milliseconds, pinpoint exactly which unit is broken, and provide a safety net for refactoring without fear of regression.

Common Mistakes

  • Tests that test multiple units — failing tests give no indication of which unit is broken.
  • Tests with no assertions — they pass always and provide false confidence.
  • Tests tightly coupled to implementation details — refactoring breaks tests even when behaviour is correct.
  • No tests for edge cases (empty input, null, zero, max values) — bugs live in boundaries.

Code Examples

✗ Vulnerable
// Test with no assertion — always passes:
public function testProcess(): void {
    $service = new OrderService();
    $service->process($order); // Called but nothing asserted
    // PHPUnit reports: 1 test, 0 assertions — misleadingly green
}

// With assertions:
public function testProcess(): void {
    $result = $service->process($order);
    $this->assertSame('processed', $result->status);
    $this->assertTrue($result->emailSent);
}
✓ Fixed
use PHPUnit\Framework\TestCase;

class MoneyTest extends TestCase {
    public function test_add_same_currency(): void {
        $a = new Money(100, 'GBP');
        $b = new Money(50, 'GBP');
        $this->assertEquals(new Money(150, 'GBP'), $a->add($b));
    }

    public function test_add_different_currency_throws(): void {
        $this->expectException(CurrencyMismatch::class);
        (new Money(100, 'GBP'))->add(new Money(100, 'USD'));
    }
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 91
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 0 pings S 0 pings S 0 pings M 1 ping T 4 pings W 2 pings T 3 pings F 5 pings S 14 pings S 3 pings M 2 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 1 ping S 1 ping M 2 pings T 0 pings W
No pings yet today
PetalBot 1 Google 1
Scrapy 30 Amazonbot 10 Perplexity 10 Ahrefs 5 SEMrush 5 Google 4 Bing 3 Unknown AI 2 Claude 2 PetalBot 2 Majestic 1 Qwen 1 ChatGPT 1 Meta AI 1 Common Crawl 1
crawler 75 crawler_json 3
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Test one unit of behaviour per test, arrange-act-assert pattern, inject all dependencies so they can be mocked — test the what not the how
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
No test directory or test coverage <40% or tests hitting real database/filesystem/network
Auto-detectable: ✓ Yes phpunit pest phpstan infection
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant