logo
podcast Podcast
get help Get Unstuck

Strengthen your tests by being negative

Not that kind of negative

Joel Clermont
Joel Clermont
2024-08-27

Whenever I'm testing something that does filtering or searching, I like to make sure I generate a few records that should not be returned by my test.

And for good measure, I like to mix in these records with the ones that should be returned. So if I'm creating 5 records that should be returned and 3 that should not be returned, I'd alternate between those in my test setup, not just create them all at the end.

Even better, I'll assign those unexpected records to a descriptively-named variable, like $userNotMatchingRole. I won't ever use that variable, but it makes the test more readable.

After calling the controller or method being tested, I like to have two types of assertions:

First, I'll assert the exact count of records returned. If this is wrong, I want it to fail first.

Then, I'll assert which specific records were returned, matching on some known unique field, so there's no ambiguity.

With this approach, you have more confidence that the logic is working exactly as expected. If you only create records you want to return, you aren't fully testing your filter logic.

As a side note, this approach doesn't work if your test suite relies on a giant global seeder. This is one more reason I recommend having the database as empty as possible for tests, and only create the exact records that test needs, as it needs it.

Here to help,

Joel

P.S. Today is Laracon!! Come join the Mastering Laravel community and geek out with us!

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice you can use.