Writing a good unit test and reporting a bug in a way the team can act on are the same discipline applied at two different moments: communicating clearly what happened, and what should have happened.
This is a short guide to structuring a test, choosing test doubles, and reporting a reproducible bug.
1. Start with a clear unit test
A direct summary of PHPUnit best practices:
- Be descriptive about what you’re testing.
- Be explicit about what you’re testing.
- Use the most specific assertion possible —
assertCount(3, $items)instead ofassertTrue(count($items) === 3). - Decouple test code from test data. If the data changes, the test shouldn’t have to change with it.
- Use a configuration file instead of scattering manual setup across tests.
- Write real unit tests — use stubs and mocks when it makes sense, not as an automatic reflex.
2. Structure the test with the Triple A pattern
- Arrange: set up the test — variables, mocks, spies.
- Act: run the thing being tested.
- Assert: check that the result matches what’s expected.
Visually separating these three steps in the code — even with just a blank line between them — already makes the test easier to read six months later.
3. Choose between a stub and a mock
- Stub: a simple fake object that just makes sure the test runs without breaking on external dependencies.
- Mock: a smarter stub — you verify the test passed through it, checking that it was called the right way.
Confusing the two is common, and the practical effect is using a mock where a stub would already do the job — leaving the test more coupled to the implementation than it needs to be.
4. Report the bug with enough context
- Problem description: objective and clear, stating whether it’s always reproducible or intermittent. Example: “On the login screen, typing the password doesn’t mask the characters.”
- Severity: does the bug block you from continuing to test? High. If not, medium or low, depending on context.
- Steps to reproduce: step by step, don’t skip any.
- Environment and version: where it happened — staging, dev, production — and which version.
- Platform: browser, operating system, specific app.
- Evidence: screenshot, video, log.
The same principle, two moments
A well-designed test — AAA applied with the right test doubles — is already halfway to a bug, when it appears, being easy to report and reproduce. That’s not a coincidence: both require the same clarity about what’s expected, what was observed, and exactly where the difference showed up.