数据库测试 
介绍 
Laravel 提供了多种有用的工具和断言,使得测试数据库驱动的应用程序变得更加容易。此外,Laravel 的模型工厂和填充器使得使用应用程序的 Eloquent 模型和关系创建测试数据库记录变得轻松。我们将在接下来的文档中讨论所有这些强大的功能。
每个测试后重置数据库 
在进一步讨论之前,让我们讨论如何在每个测试后重置数据库,以便前一个测试的数据不会干扰后续测试。Laravel 提供的 Illuminate\Foundation\Testing\RefreshDatabase trait 可以为你处理这个问题。只需在你的测试类中使用该 trait:
<?php
namespace Tests\Feature;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class ExampleTest extends TestCase
{
    use RefreshDatabase;
    /**
     * 一个基本的功能测试示例。
     */
    public function test_basic_example(): void
    {
        $response = $this->get('/');
        // ...
    }
}Illuminate\Foundation\Testing\RefreshDatabase trait 不会在你的数据库架构是最新的情况下迁移数据库。相反,它只会在数据库事务中执行测试。因此,任何不使用此 trait 的测试用例添加到数据库的记录可能仍然存在于数据库中。
如果你想完全重置数据库,可以使用 Illuminate\Foundation\Testing\DatabaseMigrations 或 Illuminate\Foundation\Testing\DatabaseTruncation traits。然而,这两种选项都比 RefreshDatabase trait 慢得多。
模型工厂 
在测试时,你可能需要在执行测试之前向数据库插入一些记录。与其手动指定每个列的值来创建这些测试数据,Laravel 允许你为每个 Eloquent 模型 使用 模型工厂 定义一组默认属性。
要了解更多关于创建和使用模型工厂来创建模型的信息,请查阅完整的 模型工厂文档。一旦定义了模型工厂,你可以在测试中使用工厂来创建模型:
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 Tests\TestCase;
class ExampleTest extends TestCase
{
    use RefreshDatabase;
    /**
     * 测试创建新订单。
     */
    public function test_orders_can_be_created(): void
    {
        // 运行 DatabaseSeeder...
        $this->seed();
        // 运行特定的填充器...
        $this->seed(OrderStatusSeeder::class);
        // ...
        // 运行一组特定的填充器...
        $this->seed([
            OrderStatusSeeder::class,
            TransactionStatusSeeder::class,
            // ...
        ]);
    }
}或者,你可以指示 Laravel 在每个使用 RefreshDatabase trait 的测试之前自动填充数据库。你可以通过在基础测试类中定义一个 $seed 属性来实现这一点:
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
    use CreatesApplication;
    /**
     * 指示是否在每个测试之前运行默认填充器。
     *
     * @var bool
     */
    protected $seed = true;
}当 $seed 属性为 true 时,测试将在每个使用 RefreshDatabase trait 的测试之前运行 Database\Seeders\DatabaseSeeder 类。然而,你可以通过在测试类中定义一个 $seeder 属性来指定应该执行的特定填充器:
use Database\Seeders\OrderStatusSeeder;
/**
 * 在每个测试之前运行特定的填充器。
 *
 * @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);
// 测试...