jbtje
2 years ago
309
5
Laravel

UnitTest with pre-seeded database and persistent content in Laravel 5.5

Posted 2 years ago by jbtje

The problem: I need to pre-seed my database with specific data, before I can run the unit tests. However, I want the data to remain after the first test. Furthermore, I want changes in the database to remain over multiple test, thus it should be persistent.

Now I've searched for this problem, however have not yet found the solution. phpUnit runs the SetUp() function once before each test. Thus, it is possible to run:

    public function setUp()
    {
        parent::setUp();
        \Artisan::call( 'migrate' );
        \Artisan::call( 'db:seed' );
    }

once before every test. This would work, however the database will be reset after each test.

Another method would be to use

    public static function setUpBeforeClass()
    {
        parent::setUpBeforeClass();

        // Seed the database with data once.
        \Artisan::call( 'migrate' );
        \Artisan::call( 'db:seed' );
    }

In theory, this would run once, however results in: Class "Artisan" not found. I guess the initialisation is not yet done by the time this function is called, so that doesn't work either. A possible solution would be to use shell_exec( 'php artisan migrate --seed' );. But, I have a test database defined in phpunit.xml while this command will seed the local database. I don't know if it is possible tell artisan to use the settings overwrite from phpunit.xml?

Q1) How to properly instruct laravel/phpunit to seed the database once, before running?

Then there is yet another problem. I want the data in my database to be persistent between some tests. I do understand that it is not best practice, but I have some specific situations which I would rather write in multiple tests instead of putting them all in one. In Laravel 5.5 however it seems that by default the database is rolled back after each test (Guess I'm doing something wrong?) The documentation notes that ony if you add use RefreshDatabase; it will refresh the database (to the previous state???) I did a simpel test with a clean install:

<?php

namespace Tests\Feature;

use App\Post;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class ExampleTest extends TestCase
{
    use DatabaseMigrations;

    public function test_hello_world( )
    {
        Post::create(['name' => 'Hello']);

        $post = Post::first();
        $this->assertEquals('Hello', $post->name);
    }

    public function test_hello_world2( )
    {
        $post = Post::firstOrFail();
        $this->assertEquals('Hello', $post->name);
    }
}

when running

C:\Webserver\PHP7.1.8\php.exe -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=127.0.0.1 Z:/Webserver/www/Laravel/Test/vendor/phpunit/phpunit/phpunit --configuration Z:\Webserver\www\Laravel\Test\phpunit.xml Tests\Feature\ExampleTest Z:\Webserver\www\Laravel\Test\tests\Feature\ExampleTest.php --teamcity

returns True for the first test, and No query results for model [App\Post]. for the second.

Q2) Any suggestions on what I'm doing wrong?

Please sign in or create an account to participate in this conversation.