Skip to content

데이터베이스 테스팅

소개

라라벨은 데이터베이스 기반 애플리케이션을 더 쉽게 테스트할 수 있도록 다양한 유용한 도구와 어설션을 제공합니다. 또한 라라벨 모델 팩토리와 시더를 사용하면 애플리케이션의 Eloquent 모델 및 관계를 사용하여 테스트 데이터베이스 레코드를 쉽게 만들 수 있습니다. 다음 문서에서 이러한 강력한 기능들을 모두 살펴보겠습니다.

각 테스트 후 데이터베이스 재설정

더 자세히 진행하기 전에 이전 테스트의 데이터가 후속 테스트를 방해하지 않도록 각 테스트 후에 데이터베이스를 재설정하는 방법에 대해 논의해 보겠습니다. 라라벨에 포함된 Illuminate\Foundation\Testing\RefreshDatabase 트레이트가 이 작업을 처리해 줄 것입니다. 간단히 테스트 클래스에서 트레이트를 사용하세요:

<?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 트레이트는 스키마가 최신 상태인 경우 데이터베이스를 마이그레이션하지 않습니다. 대신 데이터베이스 트랜잭션 내에서만 테스트를 실행합니다. 따라서 이 트레이트를 사용하지 않는 테스트 케이스에서 데이터베이스에 추가된 레코드는 데이터베이스에 여전히 존재할 수 있습니다.

데이터베이스를 완전히 재설정하려면 Illuminate\Foundation\Testing\DatabaseMigrations 또는 Illuminate\Foundation\Testing\DatabaseTruncation 트레이트를 대신 사용할 수 있습니다. 그러나 이러한 두 옵션 모두 RefreshDatabase 트레이트보다 훨씬 느립니다.

모델 팩토리

테스트 시 테스트를 실행하기 전에 데이터베이스에 몇 개의 레코드를 삽입해야 할 수 있습니다. 이 테스트 데이터를 생성할 때 각 열의 값을 수동으로 지정하는 대신 Laravel을 사용하면 모델 팩토리를 사용하여 Eloquent 모델 각각에 대한 기본 속성 집합을 정의할 수 있습니다.

모델을 생성하기 위해 모델 팩토리를 생성하고 활용하는 방법에 대한 자세한 내용은 전체 모델 팩토리 문서를 참조하십시오. 모델 팩토리를 정의했으면 테스트 내에서 팩토리를 사용하여 모델을 생성할 수 있습니다.

use App\Models\User;
 
test('모델을 인스턴스화할 수 있습니다', 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('주문을 생성할 수 있습니다', function () {
// DatabaseSeeder 실행...
$this->seed();
 
// 특정 시더 실행...
$this->seed(OrderStatusSeeder::class);
 
// ...
 
// 특정 시더 배열 실행...
$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;
 
/**
* 새로운 주문 생성 테스트.
*/
public function test_orders_can_be_created(): void
{
// DatabaseSeeder 실행...
$this->seed();
 
// 특정 시더 실행...
$this->seed(OrderStatusSeeder::class);
 
// ...
 
// 특정 시더 배열 실행...
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
}
}

또는, RefreshDatabase 트레이트를 사용하는 각 테스트 전에 Laravel이 자동으로 데이터베이스를 시딩하도록 지시할 수 있습니다. 기본 테스트 클래스에서 $seed 속성을 정의하여 이를 수행할 수 있습니다:

<?php
 
namespace Tests;
 
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
 
abstract class TestCase extends BaseTestCase
{
/**
* 기본 시더가 각 테스트 전에 실행되어야 하는지 여부를 나타냅니다.
*
* @var bool
*/
protected $seed = true;
}

$seed 속성이 true이면, 테스트는 RefreshDatabase 트레이트를 사용하는 각 테스트 전에 Database\Seeders\DatabaseSeeder 클래스를 실행합니다. 그러나 테스트 클래스에 $seeder 속성을 정의하여 실행해야 하는 특정 시더를 지정할 수 있습니다:

use Database\Seeders\OrderStatusSeeder;
 
/**
* 각 테스트 전에 특정 시더를 실행합니다.
*
* @var string
*/
protected $seeder = OrderStatusSeeder::class;

사용 가능한 어설션

Laravel은 Pest 또는 PHPUnit 기능 테스트를 위한 여러 데이터베이스 어설션을 제공합니다. 아래에서 이러한 각 어설션을 살펴보겠습니다.

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);
 
// 테스트...