【问题标题】:Tests in Laravel - run database migrations just once per file, rather than for every individual testLaravel 中的测试 - 每个文件只运行一次数据库迁移,而不是每个单独的测试
【发布时间】:2020-12-25 19:38:34
【问题描述】:

在我的 Laravel 应用程序中,我有大量的 MySql 表和大量的 phpunit 测试要运行。我使用 Sqlite 在内存中运行测试,并使用一系列 Seeder 文件将数据添加到测试数据库。

对于每个测试,Laravel 都会创建一个新数据库,运行迁移并添加数据,这会花费大量时间乘以测试数量。

我想指定对于某些测试文件,RefreshDatabase 和 DatabaseMigrations 只需要每个文件运行一次,而不是每个测试一次。

这个功能在 Laravel 中可用吗?

【问题讨论】:

  • 我没有看到任何官方存在这种情况,但有一些解决方法可能值得检查 herehere

标签: php laravel testing migration phpunit


【解决方案1】:

如果您不想为某些测试刷新迁移,请使用以下设置方法将它们放入 Test 类中:

protected function setUp(): void
{
    RefreshDatabaseState::$migrated = true; 

    parent::setUp();
}

RefreshDatabaseState::$migrated = true; 将向 laravel 声明迁移已经发生,不必再次播放

【讨论】:

  • 谢谢!尽管我很害怕,但对我来说似乎没有任何区别。我会进一步调查!
  • 这与不使用 refresh trait 有何不同?
【解决方案2】:

您可以尝试以下方法:

use Illuminate\Foundation\Testing\DatabaseTransactions;

class YourTest extends TestCase
{
    use DatabaseTransactions;

    protected function setUp(): void
    {
        parent::setUp();

        $this->artisan('migrate');
    }

    /** @test */
    public function itDoesTheThing()
    {
        // code
    }
}

这里我们使用DatabaseTransactions trait,所以我们在测试中所做的一切都将包装在事务中并在每次测试后回滚,然后在setUp 方法中,我们为每个测试迁移数据库,但它只会做第一次测试,因为数据库会在第一次测试后迁移。

另一种选择是使用一个属性来确定您是否已经迁移/播种了数据库,如下所示:

class YourTest extends TestCase
{
    use DatabaseTransactions;

    protected static $initialized = false;

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

        if (!self::$initialized) {
            // migrate and seed the database for each test only once

            self::$initialized = true;
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-07
    • 2016-04-26
    • 1970-01-01
    • 2016-12-13
    • 2011-02-13
    • 2011-02-22
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多