Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to seed database migrations for laravel tests?

Laravel's documentation recommends using the DatabaseMigrations trait for migrating and rolling back the database between tests.

use Illuminate\Foundation\Testing\DatabaseMigrations;  class ExampleTest extends TestCase {     use DatabaseMigrations;      /**      * A basic functional test example.      *      * @return void      */     public function testBasicExample()     {         $response = $this->get('/');          // ...     } } 

However, I've got some seed data that I would like to use with my tests. If I run:

php artisan migrate --seed 

then it works for the first test, but it fails subsequent tests. This is because the trait rolls back the migration, and when it runs the migration again, it doesn't seed the database. How can I run the database seeds with the migration?

like image 836
Jeff Puckett Avatar asked Feb 20 '17 16:02

Jeff Puckett


People also ask

How do I seed a DB in Laravel?

Laravel includes the ability to seed your database with data using seed classes. All seed classes are stored in the database/seeders directory. By default, a DatabaseSeeder class is defined for you. From this class, you may use the call method to run other seed classes, allowing you to control the seeding order.

How do you generate migrations in Laravel?

To create a new migration, you can run the make:migration Artisan command and that will bootstrap a new class on your Laravel application, in the database/migrations folder. This class will contain a default boilerplate code.

What are database migrations and seeds?

Migrations and seeders are powerful database utilities provided by the Laravel PHP framework to allow developers to quickly bootstrap, destroy and recreate an application's database.


2 Answers

All you need to do is make an artisan call db:seed in the setUp function

<?php  use Illuminate\Foundation\Testing\DatabaseMigrations;  class ExampleTest extends TestCase {     use DatabaseMigrations;      public function setUp(): void     {         parent::setUp();          // seed the database         $this->artisan('db:seed');         // alternatively you can call         // $this->seed();     }      /**      * A basic functional test example.      *      * @return void      */     public function testBasicExample()     {         $response = $this->get('/');          // ...     } } 

ref: https://laravel.com/docs/5.6/testing#creating-and-running-tests

like image 103
lasec0203 Avatar answered Sep 21 '22 23:09

lasec0203


It took me some digging to figure this out, so I thought I'd share.

If you look at the source code for the DatabaseMigrations trait, then you'll see it has one function runDatabaseMigrations that's invoked by setUp which runs before every test and registers a callback to be run on teardown.

You can sort of "extend" the trait by aliasing that function, re-declare a new function with your logic in it (artisan db:seed) under the original name, and call the alias inside it.

use Illuminate\Foundation\Testing\DatabaseMigrations;  class ExampleTest extends TestCase {     use DatabaseMigrations {         runDatabaseMigrations as baseRunDatabaseMigrations;     }      /**      * Define hooks to migrate the database before and after each test.      *      * @return void      */     public function runDatabaseMigrations()     {         $this->baseRunDatabaseMigrations();         $this->artisan('db:seed');     }      /**      * A basic functional test example.      *      * @return void      */     public function testBasicExample()     {         $response = $this->get('/');          // ...     } } 
like image 38
Jeff Puckett Avatar answered Sep 19 '22 23:09

Jeff Puckett