testing

  • Fixtures that build objects, not rows

    A fixture written as SQL or as an array of columns encodes the schema into every test, so a column rename breaks two hundred tests that have nothing…

  • Upgrading a production application to PHP 7

    Twice the throughput and half the memory, for a migration that is mostly deletions — plus the four behaviour changes nobody puts in the upgrade notes.

  • A smoke test is not an integration test

    Both hit a running system, so they get put in the same suite and run at the same time. They answer different questions and should fail at different…

  • Testing time-dependent code means injecting the clock

    Code that calls time() or new DateTime() internally cannot be tested at a chosen moment. The usual workarounds are a sleep() in the test, which makes the suite…

  • PHPUnit data providers turn six tests into one

    Testing the same behaviour across several inputs usually produces six near-identical methods, and when the assertion needs changing it has to change six times. A data provider separates…

  • A mock asserts an interaction; a stub only answers

    PHPUnit builds both with the same method, which is why the distinction gets lost. A stub exists to let the test proceed — it returns a value. A…

  • Restructuring an application for Laravel 5

    4.2 to 5.0 is not an upgrade, it is a relocation. Moving an application through it in an order that keeps it booting at every step.

  • Interface segregation shows up as a mock with six stubs

    The principle is abstract until you write the test. If exercising one method means stubbing five others that the code under test never calls, the interface is doing…

  • Coverage without @covers reports code you never tested

    Coverage records every line executed during a test, not every line the test was checking. A unit test for an invoice calculator that happens to construct three collaborators…

  • Moving a legacy PHP application onto Composer and PSR-4

    Two hundred and forty require_once calls where load order was load-bearing, moved onto an autoloader one namespace at a time without a big-bang rewrite.