Laravel Dusk: how to use in-memory DB for testing

2020-07-18 04:28发布

问题:

What I've been trying is to use in-memory database while testing with Laravel Dusk.

Here we have a file, .env.dusk.local, with the following values.

DB_CONNECTION=sqlite
DB_DATABASE=:memory:

Here is a snippet of a browser testing file.

class ViewOrderTest extends DuskTestCase
{
    use DatabaseMigrations;

    /** @test */
    public function user_can_view_their_order()
    {
        $order = factory(Order::class)->create();

        $this->browse(function (Browser $browser) use ($order) {
            $browser->visit('/orders/' . $order->id);
            $browser->assertSee('Order ABC'); //Order name
        });
    }
}

When php artisan dusk is executed, Dusk starts browser testing.

However, Dusk seems to be accessing my local DB, because there is an order name on the testing browser which only exists in my local DB, while 'Order ABC' is expected to be displayed on the browser.

According to the doc, Laravel Dusk allows us to set the environmental variables.

To force Dusk to use its own environment file when running tests, create a .env.dusk.{environment} file in the root of your project. For example, if you will be initiating the dusk command from your local environment, you should create a .env.dusk.local file.

I don't feel that Dusk is accessing the seperate DB.

Any advice will be appreciated.

回答1:

You can't use :memory: database while Laravel dusk browser testing. Your development server and dusk testing runs on separate processes. dust test cannot access to memory of process running on development server.

Best solution it to create sqlite file database for testing.

'sqlite_testing' => [
      'driver'   => 'sqlite',
      'database' => database_path('sqlite.testing.database'),
      'prefix'   => '',
 ],

Create sqlite.testing.database file inside database folder.

Make sure to run development server before running tests using

php artisan serve --env dusk.local


回答2:

You need a connection in config/database.php

'sqlite_testing' => [
     'driver'   => 'sqlite',
     'database' => ':memory:',
     'prefix'   => '',
],

Then in your phpunit.xml file use:

<env name="DB_DEFAULT" value="sqlite_testing" />

or in your tests use:

 putenv('DB_DEFAULT=sqlite_testing');

Don't forget to use the RefreshDatabase trait to reset the database before each test.