Php testing skill

Write unit and integration tests for PHP applications with PHPUnit and Pest.

by HoangNguyen0403·MIT license·★ 569 Stars on the repo·GitHub ↗

Use now

Files of Php testing

HoangNguyen0403/develop1 file shown
SKILL.md
Show the full text58 lines

PHP Testing

Priority: P1 (HIGH)

Core Rule Anchors

  • [BE-TEST-01] Parameterized Tests for Equivalent Cases: Prefer #[DataProvider] (PHPUnit) or dataset (Pest) when methods have multiple equivalent inputs or boundary permutations. Distinct scenarios may stay separate test methods. Reviewers must not demand parameterized rewrites without a behavioral gap.
  • [BE-TEST-02] Ban on Brittle DB Mock String Matching: Do not use string-matching mocks for raw SQL queries. Test pure domain calculations directly, or use SQLite in-memory / real DB for database repository verification.
  • [BE-TEST-03] Ban on Shallow Assertions: Never assert only assertNotNull($result) without inspecting domain fields, status codes, and invariants.
  • [BE-TEST-04] Ban on Pass-Through Interface Mocks: Repositories and service handlers must test contract compliance and error mapping. Ban 1:1 pass-through mock echoing without contract assertions.
  • [BE-TEST-05] Bug-First Regression Lock: Every PR fixing a bug ticket or with title fix(...) must introduce a test reproducing the defect prior to the fix.

Write Tests with PHPUnit and Pest

  • Standards: Use PHPUnit (9/10+) or Pest. Organize into Unit/, Integration/, and Feature/. Class names should extend TestCase.
  • TDD Workflow ([BE-TEST-05]): Follow Red-Green-Refactor. Write failing test first, implement minimal logic, then refactor.
  • Fluent Assertions ([BE-TEST-03]): Use assertSame (===) over assertEquals to avoid type coercion. Also use assertCount() and assertMatchesRegularExpression(). Avoid shallow assertions.
  • Data Providers ([BE-TEST-01]): Use #[DataProvider('statusProvider')] (PHPUnit 10+) or dataset (Pest).
  • Mocking & Isolation ([BE-TEST-02], [BE-TEST-04]): Use createMock() for dependencies; ban 1:1 pass-through mock echoing. Ensure tests are independent and repeatable. DB tests must use Transactions or SQLite :memory:.
  • Coverage: Coverage is diagnostic and project-configured; verify risk-weighted critical paths rather than padding code for an arbitrary percentage.

Anti-Patterns

  • [BE-TEST-01] Stylistic parameterized rewrites: Do not demand data provider rewrites without a behavioral gap.
  • [BE-TEST-02] Brittle DB mock string matching: Do not match SQL strings in mocks.
  • [BE-TEST-03] Shallow assertions: Never assert only assertNotNull without domain payload checks.
  • [BE-TEST-04] Pass-through mock echoing: Ban 1:1 mock echoing without contract assertions.
  • [BE-TEST-05] Bug fix without reproduction test: Ban bug fixes without a reproduction test.
  • No testing private methods: Test through public interfaces only.
  • No over-mocking internals: Mock only external boundaries.
  • No real network/DB in unit tests: Use in-memory databases or mocks.
  • No coverage-metric chasing: Prioritize meaningful assertions over arbitrary percentage metrics.

References

Canonical response anchors

When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:

  • Define a static method returning test cases as arrays,method
  • independent
  • type coercion
1---
2name: php-testing
3description: Write unit and integration tests for PHP applications with PHPUnit and Pest. Use when writing PHPUnit unit tests or integration tests for PHP applications.
4metadata:
5 triggers:
6 files:
7 - 'tests/**/*.php'
8 - 'phpunit.xml'
9 keywords:
10 - phpunit
11 - pest
12 - mock
13 - assert
14 - tdd
15---
16# PHP Testing
17 
18## **Priority: P1 (HIGH)**
19 
20## Core Rule Anchors
21 
22- **`[BE-TEST-01]` Parameterized Tests for Equivalent Cases**: Prefer `#[DataProvider]` (PHPUnit) or `dataset` (Pest) when methods have multiple equivalent inputs or boundary permutations. Distinct scenarios may stay separate test methods. Reviewers must not demand parameterized rewrites without a behavioral gap.
23- **`[BE-TEST-02]` Ban on Brittle DB Mock String Matching**: Do not use string-matching mocks for raw SQL queries. Test pure domain calculations directly, or use SQLite in-memory / real DB for database repository verification.
24- **`[BE-TEST-03]` Ban on Shallow Assertions**: Never assert only `assertNotNull($result)` without inspecting domain fields, status codes, and invariants.
25- **`[BE-TEST-04]` Ban on Pass-Through Interface Mocks**: Repositories and service handlers must test contract compliance and error mapping. Ban 1:1 pass-through mock echoing without contract assertions.
26- **`[BE-TEST-05]` Bug-First Regression Lock**: Every PR fixing a bug ticket or with title `fix(...)` must introduce a test reproducing the defect prior to the fix.
27 
28## Write Tests with PHPUnit and Pest
29 
30- **Standards**: Use **`PHPUnit`** (9/10+) or **`Pest`**. Organize into **`Unit/`**, **`Integration/`**, and **`Feature/`**. Class names should extend **`TestCase`**.
31- **TDD Workflow (`[BE-TEST-05]`)**: Follow **Red-Green-Refactor**. Write failing test first, implement minimal logic, then refactor.
32- **Fluent Assertions (`[BE-TEST-03]`)**: Use **`assertSame`** (`===`) over `assertEquals` to avoid type coercion. Also use **`assertCount()`** and **`assertMatchesRegularExpression()`**. Avoid shallow assertions.
33- **Data Providers (`[BE-TEST-01]`)**: Use **`#[DataProvider('statusProvider')]`** (PHPUnit 10+) or **`dataset`** (Pest).
34- **Mocking & Isolation (`[BE-TEST-02]`, `[BE-TEST-04]`)**: Use **`createMock()`** for dependencies; ban 1:1 pass-through mock echoing. Ensure tests are independent and repeatable. DB tests must use **`Transactions`** or **`SQLite :memory:`**.
35- **Coverage**: Coverage is diagnostic and project-configured; verify risk-weighted critical paths rather than padding code for an arbitrary percentage.
36 
37## Anti-Patterns
38 
39- **`[BE-TEST-01]` Stylistic parameterized rewrites**: Do not demand data provider rewrites without a behavioral gap.
40- **`[BE-TEST-02]` Brittle DB mock string matching**: Do not match SQL strings in mocks.
41- **`[BE-TEST-03]` Shallow assertions**: Never assert only `assertNotNull` without domain payload checks.
42- **`[BE-TEST-04]` Pass-through mock echoing**: Ban 1:1 mock echoing without contract assertions.
43- **`[BE-TEST-05]` Bug fix without reproduction test**: Ban bug fixes without a reproduction test.
44- **No testing private methods**: Test through public interfaces only.
45- **No over-mocking internals**: Mock only external boundaries.
46- **No real network/DB in unit tests**: Use in-memory databases or mocks.
47- **No coverage-metric chasing**: Prioritize meaningful assertions over arbitrary percentage metrics.
48## References
49 
50- [Testing Patterns & Mocks](references/implementation.md)
51 
52## Canonical response anchors
53 
54When this skill applies, preserve the following domain terminology or equivalent concrete examples in the answer when relevant:
55- Define a static method returning test cases as arrays,method
56- independent
57- type coercion
58 

Discussion

Alternatives