The reporting code had one caller and a six-hour test run. Finding the seam, dealing with the shared schema honestly, and routing traffic gradually rather than switching.
Resetting the database between tests by truncating every table is correct and slow, and it re-runs the seed data on each one. Wrapping each test in a transaction…
Deploying by rsync on a Friday afternoon, and what replaced it: lint, test, build, stage, promote — with a rollback that is the same mechanism rather than a…
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…
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…
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…
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…
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…