You don't need to manually run seeders in your tests

Laravel is constantly making things nicer

Joel Clermont
Joel Clermont

The Laravel TestCase supports a $seed property. When you set this to true and also use the RefreshDatabase trait, it then automatically seeds your database using the default seeder.

This feature isn't exactly new. It was added in Laravel 8. But I still bump into applications where it's not being used. Instead, $this->seed() is being called manually within the test or in the base setup() method.

Why is using this new property better? Is it just about saving the need to write a few lines of code? Not at all! It's actually a huge performance improvement.

The RefreshDatabase trait starts each test run with artisan migrate:fresh and then wraps every individual test in a database transaction. At the end of each individual test execution, the transaction is rolled back, so each test runs in a pristine database. This helps a ton to reduce test flakiness.

But when using the $seed property, it runs artisan migrate:fresh --seed. So that seeder is only being run one time for the entire test run, not once for each individual test within the suite. As your test suite grows, you'll save more and more time with this handy feature.

If you're wondering what we put in the seeder, stay tuned for tomorrow's tip...

Here to help,


P.S. Testing is such an important topic, but we still see a lot of projects with minimal tests. If that sounds like your project, hit reply and let me know what is holding you back from writing more tests.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼

Level up your Laravel skills!

Each 2-minute email has real-world advice you can use.