在 Laravel/phpunit 中保留 sqlite 数据库进行多次测试以减少所需时间

Jon*_*ley 6 php sqlite phpunit laravel

我有很多测试,运行所有测试需要很长时间 ~ 15 分钟。这主要是由于构建新的 sqlite 数据库并对其进行播种的大量测试。

我的很多测试都不会更改数据库,因此它们都可以在同一个数据库上运行,该数据库仅创建一次。但是,我不知道如何设置我的测试来像这样工作。

我在 Laravel 中使用内存中的 sqlite。

我试图阻止我的 phpunit 测试每次创建和播种数据库。

我最新的尝试是使用此处详细说明的特征:/sf/answers/4045168641/

但是,当我运行测试时,第一个测试顺利通过(因此数据库表存在),然后文件中的第二个测试失败并显示:“一般错误:1 没有这样的表:用户”。

./bin/phpunit ./tests/Auth/UserTest.php
Run Code Online (Sandbox Code Playgroud)

因此,第一次测试后数据库表已被擦除。

我尝试过重写tearDown 方法,但没有什么区别。

什么可能会擦除我的数据库?

<?php

namespace Tests\Auth;

use Tests\TestCase;
use Tests\MigrateFreshAndSeedOnce;
use App\Entity\Models\User;

class UserTest extends TestCase
{

    use MigrateFreshAndSeedOnce;

    public function testUser1()
    {
        $user = User::where('id', 1)->get()->first();
        $this->assertTrue($user->id !== null);
    }

    public function testUser2()
    {
        $user = User::where('id', 2)->get()->first();
        $this->assertTrue($user->id !== null);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是特点:

<?php

namespace Tests;

use Illuminate\Support\Facades\Artisan;

trait MigrateFreshAndSeedOnce
{

    /**
     * If true, setup has run at least once.
     *
     * @var boolean
     */
    protected static $setUpHasRunOnce = false;

    /**
     *
     * @return void
     */
    public function setUp() : void
    {
        parent::setUp();

        if (!static::$setUpHasRunOnce) {

            echo '--DB--';
            Artisan::call('migrate:fresh');

            Artisan::call(
                'db:seed',
                ['--class' => 'DatabaseSeeder'] //add your seed class
            );

            static::$setUpHasRunOnce = true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,我的测试用例类:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    protected $baseUrl = 'http://dev.php73.mysite.com:8888';
}
Run Code Online (Sandbox Code Playgroud)

我的 phpunit 环境变量:

    <php>
        <env name="APP_ENV" value="testing"/>
        <env name="CACHE_DRIVER" value="array"/>
        <env name="SESSION_DRIVER" value="array"/>
        <env name="QUEUE_DRIVER" value="sync"/>
        <env name="DB_CONNECTION" value="testing" />
    </php>
Run Code Online (Sandbox Code Playgroud)

谢谢!

Mik*_*cid -1

正如 @matiaslauriti 在评论中所述,对于 Laravel 8,您应该使用 RefreshDatabase 特征。一旦应用,它将寻找一个名为 的布尔属性seed

$seed如果您希望将不需要刷新的测试播种并移动到另一个测试类,请为您的测试类提供 protected 属性并将其设置为 true。

class ProjectControllerTest extends TestCase
{

    protected $seed = true;
}
Run Code Online (Sandbox Code Playgroud)

然后只有必要的测试才会构建数据库。

或者使用:

$this->seed(); 
Run Code Online (Sandbox Code Playgroud)

在测试方法内,为特定测试提供种子。

查看其文档