home / skills / makfly / superpowers-symfony / tdd-with-phpunit

tdd-with-phpunit skill

/skills/tdd-with-phpunit

This skill accelerates Symfony development with deterministic TDD using PHPUnit, turning bugs into failing tests and ensuring regression protection.

npx playbooks add skill makfly/superpowers-symfony --skill tdd-with-phpunit

Review the files below or copy the command above to add this skill to your agents.

Files (2)
SKILL.md
1.1 KB
---
name: symfony:tdd-with-phpunit
allowed-tools:
  - Read
  - Write
  - Edit
  - Bash
  - Glob
  - Grep
description: Drive Symfony delivery with deterministic tests and strong regression protection. Use for tdd with phpunit tasks.
---

# Tdd With Phpunit (Symfony)

## Use when
- Building regression-safe behavior with TDD/functional/e2e tests.
- Converting bug reports into executable failing tests.

## Default workflow
1. Write failing test for target behavior and one boundary case.
2. Implement minimal code to pass.
2. Refactor while preserving green suite.
2. Broaden coverage for invalid/unauthorized/not-found paths.

## Guardrails
- Prefer deterministic fixtures/builders.
- Assert observable behavior, not internal implementation.
- Keep tests isolated and stable in CI.

## Progressive disclosure
- Use this file for execution posture and risk controls.
- Open references when deep implementation details are needed.

## Output contract
- RED/GREEN/REFACTOR trace.
- Test files changed and executed commands.
- Coverage and confidence notes.

## References
- `reference.md`
- `docs/complexity-tiers.md`

Overview

This skill drives Symfony delivery using Test-Driven Development with PHPUnit to produce deterministic tests and strong regression protection. It focuses on creating failing tests first, implementing minimal code to pass, and iterating through refactor and coverage broadening. The goal is a stable CI suite that documents intended behavior and prevents regressions.

How this skill works

I guide a default red/green/refactor workflow: write a failing PHPUnit test targeting behavior, implement the smallest change to make it pass, then refactor while keeping the suite green. I emphasize deterministic fixtures and builders, isolating tests from external flakiness, and asserting observable outcomes rather than internal implementation. After the core behavior is green, I expand tests for boundary cases, invalid inputs, authorization, and not-found scenarios. I report the trace (RED/GREEN/REFACTOR), changed test files and executed commands, and include coverage and confidence notes.

When to use it

  • Developing new features in a Symfony app with behavioral guarantees
  • Converting bug reports into executable failing tests before fixing
  • Adding regression protection for critical services or APIs
  • Stabilizing flaky tests by enforcing deterministic fixtures and isolation
  • Improving confidence before refactoring complex controllers or domain logic

Best practices

  • Start each task by writing a failing PHPUnit test that targets observable behavior
  • Keep tests deterministic using builders, factories, or dedicated fixtures
  • Assert public outcomes (responses, DB state, events) instead of internals
  • Run tests in CI-like environment locally to surface timing or isolation issues early
  • Document the RED/GREEN/REFACTOR trace and list changed test files in commit messages

Example use cases

  • Drive a new API endpoint: write functional tests that assert response shape and status, implement controller logic, then broaden to auth and validation cases
  • Fix a reported bug: reproduce it with a failing test, apply the fix, and add regression tests for edge conditions
  • Refactor a service: cover current behavior with PHPUnit tests, refactor internals, and keep tests green as the safety net
  • Harden CI: replace flaky external calls with deterministic fixtures and add tests that assert the fixed behavior

FAQ

What output do I get from the skill?

A RED/GREEN/REFACTOR trace, list of test files changed, the PHPUnit commands executed, and notes on coverage and confidence.

How do I keep tests deterministic?

Use fixtures/builders, avoid time-dependent assertions, mock external services, and seed known DB states for each test.