Interacting with database is an important aspect of majority of Laravel Applications. This tutorial covers how you can work with your database in your Laravel Dusk Tests.
One of the requirement is the database to be migrated before you start running your test. Although Laravel provides three traits to work with database in your tests, DatabaseMigrations
, DatabaseTransactions
and RefreshDatabase
.
We can only make use of DatabaseMigrations
in our Laravel Dusk test, since DatabaseTransaction is not applicable in browser testing (HTTP Requests) and RefreshDatabase internally relise on DatabaseTransaction.
Using DatabaseMigrations in Dusk
If you import the DatabaseMigrations triat in your Dusk Test, it will run your entire set of database migrations up method before each test and down method after each test. That is it will create tables as per your migration file before each test and will drop them after the test.
This is how you can import DatabaseMigrations in your Dusk Test
<?php
namespace Tests\Browser;
use App\User;
use Tests\DuskTestCase;
use Laravel\Dusk\Chrome;
use Illuminate\Foundation\Testing\DatabaseMigrations;
class ExampleTest extends DuskTestCase
{
use DatabaseMigrations;
/** @test */
public function userLoginTest(){
$user = factory('App\User')->create();
$this->browse(function (Browser $browser) use($user) {
$browser->loginAs($user)
->visit('/home')
->assertSee('Dashboard');
});
}
}
DatabaseMigrations makes this happen by running php artisan migrate
in the setUp()
method before each test runs and php artisan migrate:rollback
in the tearDown()
method after each test finishes.
As you can see in the above example you can also make use of your factory methods to create a test data in the database, and then make use of the data in your dusk test.
Seeding data before running Dusk Test.
Once you have migrated your database, there can be a requirement to seed some data into the database which is required for your application to run. You can seed the data in setUp()
method of your tests.
public function setUp()
{
parent::setUp();
$this->artisan('db:seed');
}
This makes sure that the database is seeded with default data before each test.
DownSide of Using DatabaseMigrations in Dusk
Although migrating the database with just writing an import syntax is nice, but using DatabaseMigrations really slows down your dusk tests. If you have a large number of tables, DatabaseMigrations will create all tables before the test and will destroy them after the test is done.
Also, Since we cannot use in memory sqlite database with dusk, DatabaseMigrations takes time in migrating to an actual mysql or filesystem sqlite database.
So Instead of using DatabaseMigrations in my tests, I prefer these steps
- Run artisan migrate and db:seed command manually.
- Run all the dusk tests
- Rollback the database manually
It would be really nice for Laravel to create a new trait where we can migrate the database only once and then once dusk tests are completed, it rolls it back.
Update :
Speeding Up Dusk Test By Running DatabaseMigrations only once
Here is an article I came across which covers on how you can run migration only once before you start your dusk test by utilizing setUpBeforeClass of phpunit.
https://blog.pterodactyl.io/speed-up-your-laravel-dusk-tests/
Next up, Explore on how you can Use Sqlite database with dusk.