跳至內容

資料庫測試

簡介

Laravel 提供了各種有用的工具和斷言,讓您更容易測試資料庫驅動的應用程式。此外,Laravel 模型工廠和填充器讓您可以使用應用程式的 Eloquent 模型和關聯,輕鬆建立測試資料庫記錄。我們將在以下文件中討論所有這些強大的功能。

每次測試後重置資料庫

在進一步討論之前,讓我們先討論如何在每次測試後重置資料庫,以便先前的測試資料不會干擾後續的測試。Laravel 包含的 Illuminate\Foundation\Testing\RefreshDatabase trait 會為您處理此問題。只需在您的測試類別上使用此 trait

<?php
 
use Illuminate\Foundation\Testing\RefreshDatabase;
 
uses(RefreshDatabase::class);
 
test('basic example', function () {
$response = $this->get('/');
 
// ...
});
<?php
 
namespace Tests\Feature;
 
use Illuminate\Foundation\Testing\RefreshDatabase;
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 不會遷移您的資料庫。相反地,它只會在資料庫交易中執行測試。因此,未使用此 trait 的測試案例新增至資料庫的任何記錄仍可能存在於資料庫中。

如果您想要完全重置資料庫,您可以改用 Illuminate\Foundation\Testing\DatabaseMigrationsIlluminate\Foundation\Testing\DatabaseTruncation trait。但是,這兩個選項都比 RefreshDatabase trait 慢得多。

模型工廠

在測試時,您可能需要在執行測試之前將一些記錄插入資料庫中。Laravel 允許您使用 模型工廠,為每個 Eloquent 模型 定義一組預設屬性,而無需在建立此測試資料時手動指定每個欄位的值。

若要瞭解更多關於建立和利用模型工廠來建立模型,請查閱完整的模型工廠文件。定義模型工廠後,您可以在測試中使用該工廠來建立模型

use App\Models\User;
 
test('models can be instantiated', function () {
$user = User::factory()->create();
 
// ...
});
use App\Models\User;
 
public function test_models_can_be_instantiated(): void
{
$user = User::factory()->create();
 
// ...
}

執行填充器

如果您想要在功能測試期間使用 資料庫填充器來填充資料庫,您可以調用 seed 方法。預設情況下,seed 方法會執行 DatabaseSeeder,後者應該執行您所有的其他填充器。或者,您可以將特定的填充器類別名稱傳遞給 seed 方法

<?php
 
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
 
uses(RefreshDatabase::class);
 
test('orders can be created', function () {
// 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,
// ...
]);
});
<?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;
 
/**
* 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 trait 的測試之前自動填充資料庫。您可以透過在您的基本測試類別上定義 $seed 屬性來達成此目的

<?php
 
namespace Tests;
 
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
 
abstract class TestCase extends BaseTestCase
{
/**
* Indicates whether the default seeder should run before each test.
*
* @var bool
*/
protected $seed = true;
}

$seed 屬性為 true 時,測試會在每個使用 RefreshDatabase trait 的測試之前執行 Database\Seeders\DatabaseSeeder 類別。但是,您可以透過在您的測試類別上定義 $seeder 屬性,來指定應該執行的特定填充器

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

可用斷言

Laravel 為您的 PestPHPUnit 功能測試提供了幾個資料庫斷言。我們將在下面討論每個斷言。

assertDatabaseCount

斷言資料庫中的表格包含給定數量的記錄

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

assertDatabaseEmpty

斷言資料庫中的表格不包含任何記錄

$this->assertDatabaseEmpty('users');

assertDatabaseHas

斷言資料庫中的表格包含符合給定鍵值查詢限制的記錄

$this->assertDatabaseHas('users', [
'email' => '[email protected]',
]);

assertDatabaseMissing

斷言資料庫中的表格不包含符合給定鍵值查詢限制的記錄

$this->assertDatabaseMissing('users', [
'email' => '[email protected]',
]);

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...