6

I have a testsuite for a laravel project. For now I use disk file for my tests.

Question: Is there a way I can use memory database and migrate database only once before starting the test suite?

To be clear: I want to migrate the database only one time. I will have more thand 100 tests and I want only one migration to be executed

user237329
  • 809
  • 1
  • 10
  • 27
  • 1
    I believe the OP's issue is database tests are long. Partially the solution is to use in-memory DB for tests.Tests run ~5-20 (YMMV) times faster. Additionally replacing dependencies with test doubles in the test code base would help. Look at [PHPUnit test doubles](https://phpunit.readthedocs.io/en/8.2/test-doubles.html) or [Mockery](http://docs.mockery.io/en/latest/). See these videos [1](https://www.youtube.com/watch?v=_LeCyU1X5bY), [2](https://www.youtube.com/watch?v=wqd91bun7C0), [3](https://www.youtube.com/watch?v=rK8jsKqR0aI&list=PLH9Ysf6G9Ue3libSiqkuSju7_2OnQSz1w&index=7) – Valentine Shi Jul 28 '19 at 09:42
  • For convenience I [pulled the explanations together](https://stackoverflow.com/a/57229613/6597265) on how to establish in-memory testing for Laravel / Lumen and fix SQLite `Cannot add a NOT NULL column with default value NULL` that comes from using SQLite for in-memory tests. – Valentine Shi Jul 30 '19 at 09:07

1 Answers1

0

In your TestCase.php (or in any other test if you want use memory database only in that test) you can override setUp() method

public function setUp()
{
    parent::setUp();

    $this->app['config']->set('database.default', 'testing');
    $this->app['config']->set('database.connections.testing', [
        'driver' => 'sqlite',
        'database' => ':memory:',
        'prefix' => ''
    ]);
}

You can use Illuminate\Foundation\Testing\DatabaseMigrations in test class body as well. In this case, php artisan migrate:refresh will be called before each test

<?php

use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends TestCase
{
    use DatabaseMigrations;

    // ...
    // test cases
    // ...
}
Skysplit
  • 1,875
  • 12
  • 16
  • 1
    I want to call only one time before all the test suite the artisan migrate method. Otherwise there is no improvement with memory database as long I migrate for 200 times. – user237329 Aug 23 '16 at 16:02
  • There's a static method `setUpBeforeClass()` in PHPUnit. You could call `Artisan::call('migrate:refresh')` there. However, this will be called before each test case, so in `ExampleTest.php` an 'AnotherExampleTest.php` you still would have fresh databases. – Skysplit Aug 23 '16 at 16:18
  • 1
    I want to migrate only once, before the test suite! Otherwhise I could use @before or add id to setUp method – user237329 Aug 23 '16 at 18:28
  • 1
    Beside few hacks you described, there's no other option to do that, as tests are designed to be independent and should not rely on data inserted by other tests. – Skysplit Aug 24 '16 at 06:20
  • 1
    Thanks Skysplit, but @user237329 is trying to avoid migrate on every test, not do it. I have the same problem and no information when :memory: is used. – pablorsk May 28 '18 at 15:18