Training · Intermediate

Tests by Design

Test architecture: rules that people understand and agents follow

When agents write tests, it is you who decides what your tests look like, not the agent. Define which tests your project needs and which rules they follow, and let tools report every deviation.

  • Scope 2 sessions of 2 hours
  • Format Live via Zoom
  • Language German
  • Price per person €399

What it is about

Tests are written faster today than ever before. A coding agent writes them in seconds, in every style imaginable. Without rules, a test suite grows in which every test looks different, in which nobody knows which tests should exist in the first place, and which breaks in the wrong places during the next refactoring.

For you as a human to stay at the wheel, your project needs a test architecture: a decision about which expectations are verified at which level, and rules for what a test looks like. Rules alone are not enough, though, when nobody knows the reasons behind them. And rules that only exist in a document are not followed, neither by people nor by agents.

In this training you define the test architecture for a project and justify every decision. Then you make your rules checkable: with a strict PHPUnit configuration, and with PHPStan, which also analyses your test code and, thanks to its PHPUnit extension, understands what a test does.

Decide first, then enforce

The first session makes the decisions and justifies them, the second makes them checkable. Every rule gets a justification and a note on whether a tool can check it or whether it belongs in the review.

Both sessions start from the green test suite of an exercise project with domain, application, and adapter layers. It was written partly by people and partly by an agent, and it follows no shared rules.

Programme

  1. Session 1: Defining the test architecture

    Which tests does your project need, and what should they look like?

    • Staying at the wheel: an agent writes tests in any style, and without rules it decides what your suite looks like
    • The test pyramid with its levels, distribution, and costs, alternatives such as the testing trophy and the testing honeycomb, and when each of them fits
    • Test levels and architecture: domain logic in small unit tests, adapters in integration tests, a few end-to-end tests for the most important flows
    • Test suites and directories as an expression of the test strategy
    • Rules for test code, each with its reason: test names as sentences about behaviour, one behaviour per test following arrange, act, assert, no loops or conditionals in a test, assertSame() instead of assertEquals() or assertTrue($a === $b), a statement of which code a test covers
    • Rules for test doubles and test data: a stub for inputs, a mock only for verified communication, no test doubles for value objects, only replacing interfaces you own, fixtures in the test instead of a mystery guest, data providers with named data sets
    • Readable and maintainable: a test is read when it is red

    Result: A test strategy for the exercise project that defines which expectations are verified at which level, and a one-page test guideline in which every rule has a justification and a note on whether a tool can check it

  2. Session 2: Enforcing the rules

    How do you make sure that every test follows the rules, including a generated one?

    • The PHPUnit configuration as a rule: failing on risky tests, warnings, and deprecations (failOnRisky, failOnWarning), random order, no output in tests, requiring a statement of the covered code (requireCoverageMetadata) and sealed mock objects (requireSealedMockObjects)
    • Test code is code: PHPStan at the same level as for the production code
    • The PHPUnit extension for PHPStan understands assertions and mock objects and reports, for example, mocks of methods that do not exist, data providers that are referenced incorrectly, and assertions for which there is a more suitable one
    • PHP-CS-Fixer with its PHPUnit rules for a consistent notation
    • A custom PHPStan rule for a convention of the test guideline, such as “no test doubles for value objects”
    • What no tool checks: oracles, correctness against the requirements, meaningful test cases, and a checklist for the review
    • The test guideline as a rule for coding agents: briefly in the context, the rest in tools

    Result: A strict phpunit.xml and PHPStan with the PHPUnit extension that reject every test that violates the checkable rules of your test guideline, including a generated one, and a guideline for humans and agents

Who it is for

  • Tech leads and software architects who define the rules for the tests of their team
  • Experienced developers who look after test quality in their team
  • Teams who let coding agents write tests and want to stay in control while doing so

Prerequisites

  • The concepts of testing as taught in “Understanding Testing”: F.I.R.S.T., test scope, test doubles
  • A project in which PHPUnit runs, as after “Getting Started with PHPUnit”; otherwise you work on the exercise project
  • Basic knowledge of PHPStan is helpful, but not required
  • For the exercises, PHP 8.5, Composer, and Git, or alternatively Podman or Docker with the Containerfile provided

What you take away

  • You define which expectations your project verifies at which level, and you can justify it
  • You have a test guideline in which every rule has a reason
  • You configure PHPUnit so that it rejects tests that check nothing or claim too much
  • You have PHPStan analyse your test code as well, with the extension that knows PHPUnit
  • You know which rules tools check and which belong in the review
  • You take a package for your own project away: test strategy, test guideline, and a phpunit.xml and phpstan.neon for the test code

Your trainer

Sebastian Bergmann answering a participant's question at the laptop
Photo: Filip Kovačević

Sebastian Bergmann is the creator of PHPUnit, the de facto standard for testing PHP code. Since 2001 he has been helping teams build maintainable and well-tested software as a consultant and trainer, since 2009 as a co-founder of thePHP.cc.