数据库测试

Introduction

Laravel 提供了各种有用的工具和断言,可以更轻松地测试数据库驱动的应用程序。此外,Laravel 模型工厂和播种器使得使用应用程序的 Eloquent 模型和关系创建测试数据库记录变得轻松。我们将在以下文档中讨论所有这些强大的功能。

每次测试后重置数据库

在进一步进行之前,让我们讨论如何在每次测试后重置数据库,以便来自先前测试的数据不会干扰后续测试。 Laravel 的包括Illuminate\Foundation\Testing\RefreshDatabase trait 会为你解决这个问题。只需在您的测试类上使用该特征:

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * A basic functional test example.
     */
    public function test_basic_example(): void
    {
        $response = $this->get('/');

        // ...
    }
}

Illuminate\Foundation\Testing\RefreshDatabase 如果您的架构是最新的,那么 trait 不会迁移您的数据库。相反,它只会在数据库事务中执行测试。因此,由不使用此特征的测试用例添加到数据库的任何记录可能仍然存在于数据库中。

如果你想完全重置数据库,你可以使用Illuminate\Foundation\Testing\DatabaseMigrations 或者Illuminate\Foundation\Testing\DatabaseTruncation 特质代替。但是,这两个选项都比RefreshDatabase 特征。

模范工厂

测试时,您可能需要在执行测试之前向数据库中插入一些记录。 Laravel 允许您为每个测试数据定义一组默认属性,而不是在创建此测试数据时手动指定每一列的值雄辩的模型 使用样板厂.

要了解有关创建和利用模型工厂创建模型的更多信息,请查阅完整的模型工厂文件.定义模型工厂后,您可以在测试中使用该工厂来创建模型:

use App\Models\User;

public function test_models_can_be_instantiated(): void
{
    $user = User::factory()->create();

    // ...
}

运行播种机

如果您想使用数据库播种机 要在功能测试期间填充数据库,您可以调用seed 方法。默认情况下,seed 方法将执行DatabaseSeeder,它应该执行所有其他播种机。或者,您将特定的播种器类名称传递给seed 方法:

<?php

namespace Tests\Feature;

use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    use RefreshDatabase;

    /**
     * Test creating a new order.
     */
    public function test_orders_can_be_created(): void
    {
        // Run the DatabaseSeeder...
        $this->seed();

        // Run a specific seeder...
        $this->seed(OrderStatusSeeder::class);

        // ...

        // Run an array of specific seeders...
        $this->seed([
            OrderStatusSeeder::class,
            TransactionStatusSeeder::class,
            // ...
        ]);
    }
}

或者,你可以指示 Laravel 在每次使用RefreshDatabase 特征。您可以通过定义一个$seed 基础测试类的属性:

<?php

namespace Tests;

use Illuminate\Foundation\Testing\TestCase as BaseTestCase;

abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;

    /**
     * Indicates whether the default seeder should run before each test.
     *
     * @var bool
     */
    protected $seed = true;
}

当。。。的时候$seed 财产是true,测试将运行Database\Seeders\DatabaseSeeder 在使用的每个测试之前上课RefreshDatabase 特征。但是,您可以通过定义一个$seeder 测试类的属性:

use Database\Seeders\OrderStatusSeeder;

/**
 * Run a specific seeder before each test.
 *
 * @var string
 */
protected $seeder = OrderStatusSeeder::class;

可用断言

Laravel 为您提供了几个数据库断言PHPUnit 功能测试。我们将在下面讨论这些断言中的每一个。

assertDatabaseCount

断言数据库中的表包含给定数量的记录:

$this->assertDatabaseCount('users', 5);

assertDatabaseHas

断言数据库中的表包含与给定键/值查询约束匹配的记录:

$this->assertDatabaseHas('users', [
    'email' => 'sally@example.com',
]);

assertDatabaseMissing

断言数据库中的表不包含匹配给定键/值查询约束的记录:

$this->assertDatabaseMissing('users', [
    'email' => 'sally@example.com',
]);

assertSoftDeleted

assertSoftDeleted 方法可用于断言给定的 Eloquent 模型已被“软删除”:

$this->assertSoftDeleted($user);

assertNotSoftDeleted

assertNotSoftDeleted 方法可用于断言给定的 Eloquent 模型没有被“软删除”:

$this->assertNotSoftDeleted($user);

assertModelExists

断言给定模型存在于数据库中:

use App\Models\User;

$user = User::factory()->create();

$this->assertModelExists($user);

assertModelMissing

断言数据库中不存在给定模型:

use App\Models\User;

$user = User::factory()->create();

$user->delete();

$this->assertModelMissing($user);

expectsDatabaseQueryCount

expectsDatabaseQueryCount 方法可以在测试开始时调用,以指定您希望在测试期间运行的数据库查询总数。如果实际执行的查询数量与这个预期不完全匹配,测试将失败:

$this->expectsDatabaseQueryCount(5);

// Test...
豫ICP备18041297号-2