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

Parameterised / Data-Driven Tests

Testing PHP 5.0+ Intermediate
debt(d7/e3/b3/t3)
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 note automated=no, and the code pattern (multiple near-identical test methods differing only in data) is not flagged by PHPUnit or Pest automatically — it requires a human reviewer to notice the duplication and recognise the missing data-provider pattern. No static analysis tool in the provided list catches this structurally.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing 5 near-identical test methods with a single @dataProvider or Pest ->with() — this is a small, contained refactor within one test file or component, not a one-liner but not cross-cutting either. It's a clear pattern replacement within one test class.

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

Closest to 'localised tax' (b3). Misuse (duplicate test methods instead of data providers) imposes a maintenance tax scoped to the test suite for the affected component. It doesn't reach into production code or other system layers; the rest of the codebase is largely unaffected, though the test suite itself becomes harder to maintain over time.

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

Closest to 'minor surprise' (t3). The misconception field identifies that developers think separate test methods are clearer, plus there are concrete gotchas like data providers needing to be static and dataset keys needing names. These are documented, learnable surprises rather than catastrophic or deeply counterintuitive behaviour — a competent developer will hit one or two edge cases but won't be fundamentally misled.

About DEBT scoring →

Also Known As

dataProvider data-driven tests parameterised tests test matrix

TL;DR

Running the same test logic with multiple input/output pairs — PHPUnit's @dataProvider eliminates copy-pasted test methods for the same behaviour with different values.

Explanation

A data provider is a static method returning an array of arrays (or a generator) — each inner array is one test case with its named label. PHPUnit runs the test method once per dataset, naming failures with the dataset key. Use data providers for: boundary values, equivalence classes, valid/invalid input sets, and all-combinations testing. Keep the test logic in the test method; keep the data in the provider. Pest PHP offers ->with() for the same concept with cleaner syntax.

Common Misconception

A separate test method per case is clearer than a data provider — 20 test methods testing the same logic with different inputs is 20× the maintenance when the logic changes.

Why It Matters

Data providers make test matrices exhaustive without duplication — testing all valid/invalid boundary combinations becomes trivial rather than a maintenance burden.

Common Mistakes

  • Data provider method not declared static — PHPUnit requires static data providers.
  • Not naming dataset keys — assertX failed with data set #3 is unhelpful; use 'valid UK postcode' as the key.
  • Complex logic in the data provider — providers should only return data, not build objects.
  • One data provider shared across unrelated tests — keep providers focused on one test method.

Code Examples

✗ Vulnerable
// Copy-pasted test methods — O(n) maintenance:
public function testValidEmailAccepted(): void {
    $this->assertTrue(validateEmail('user@example.com'));
}
public function testInvalidEmailWithNoAt(): void {
    $this->assertFalse(validateEmail('userexample.com'));
}
public function testInvalidEmailWithNoTld(): void {
    $this->assertFalse(validateEmail('user@example'));
}
// ...15 more identical methods
✓ Fixed
/** @dataProvider emailProvider */
public function testEmailValidation(string $email, bool $expected): void {
    $this->assertSame($expected, validateEmail($email));
}

public static function emailProvider(): array {
    return [
        'valid standard email'     => ['user@example.com',  true],
        'valid with subdomain'     => ['u@sub.example.com', true],
        'invalid no at sign'       => ['userexample.com',   false],
        'invalid no TLD'           => ['user@example',      false],
        'invalid consecutive dots' => ['user..name@ex.com', false],
    ];
}

Added 16 Mar 2026
Edited 22 Mar 2026
Views 47
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 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Perplexity 8 Amazonbot 7 SEMrush 5 Ahrefs 4 Scrapy 4 Google 3 Unknown AI 3 Majestic 2 Claude 1 Meta AI 1 Bing 1
crawler 37 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Replace 5 near-identical test methods with one @dataProvider or Pest ->with() that covers all cases — it's easier to add new cases and the pattern scales to edge cases
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Multiple test methods differing only in input/output data; copy-pasted test structure with different literals
Auto-detectable: ✗ No phpunit pest
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: Medium ✗ Manual fix Fix: Low Context: Function Tests: Update


✓ schema.org compliant