testing

  • Anonymous classes make a one-off test double

    Testing a class that takes an interface usually means either a mocking framework or a small stub class in its own file, which then lives forever and is…

  • artisan tinker is a REPL with the application booted

    Checking what a relation actually returns usually means writing a throwaway route, hitting it, and deleting it — or adding a dd() somewhere and reloading. Both are slower…

  • expectException replaced the annotation

    The @expectedException annotation and setExpectedException() are both deprecated in favour of methods, which is more than a rename — the annotation asserted only that the exception was thrown…

  • The N+1 queries you did not write

    1,400 queries on a page showing 40 rows. Eager loading, the difference between with() and load(), and the accessor that no eager load can fix.

  • Deep clone an object in JavaScript

  • A test double for the clock, and one for randomness

    Two things make a test unrepeatable, and both are usually called directly from the code under test: the current time and a random number. Neither can be asserted…

  • A TypeError is something you can now catch

    Passing a string where an object was hinted used to be a recoverable fatal, which in practice meant an unrecoverable one. It is an exception now, which makes…

  • 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…