데이터베이스 테스트
업데이트됨번역일: 2026년 6월 20일
이 페이지는 원문이 업데이트되어 번역이 갱신되었습니다.
- 원문 수정
- 2026년 6월 20일
- 번역 갱신
- 2026년 6월 20일
데이터베이스 테스트
소개
Laravel은 데이터베이스 기반 애플리케이션을 테스트할 때 유용한 다양한 도구와 어서션을 제공합니다. 또한 모델 팩토리와 시더를 활용하면 Eloquent 모델과 관계를 사용하여 테스트용 데이터베이스 레코드를 간편하게 생성할 수 있습니다. 아래에서 이러한 기능들을 자세히 살펴보겠습니다.
각 테스트 후 데이터베이스 초기화
본격적으로 시작하기 전에, 테스트 간 데이터가 서로 영향을 주지 않도록 각 테스트가 끝난 후 데이터베이스를 초기화하는 방법을 알아보겠습니다. Laravel에 내장된 Illuminate\Foundation\Testing\RefreshDatabase 트레이트를 사용하면 이 작업을 자동으로 처리할 수 있습니다. 테스트 클래스에 해당 트레이트를 추가하기만 하면 됩니다.
Pest
<?php
use Illuminate\Foundation\Testing\RefreshDatabase;
pest()->use(RefreshDatabase::class);
test('기본 예제', function () {
$response = $this->get('/');
// ...
});PHPUnit
<?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('/');
// ...
}
}RefreshDatabase 트레이트는 데이터베이스 스키마가 최신 상태라면 마이그레이션을 다시 실행하지 않습니다. 대신 테스트를 데이터베이스 트랜잭션 안에서 실행하고, 테스트가 끝나면 트랜잭션을 롤백합니다. 따라서 이 트레이트를 사용하지 않는 테스트에서 추가된 레코드는 데이터베이스에 그대로 남을 수 있습니다.
NOTE
데이터베이스를 완전히 초기화하고 싶다면 Illuminate\Foundation\Testing\DatabaseMigrations 또는 Illuminate\Foundation\Testing\DatabaseTruncation 트레이트를 사용할 수 있습니다. 다만, 두 옵션 모두 RefreshDatabase보다 실행 속도가 상당히 느립니다.
모델 팩토리
테스트를 실행하기 전에 데이터베이스에 샘플 데이터를 삽입해야 하는 경우가 많습니다. 이때 각 컬럼 값을 일일이 지정하는 대신, Laravel의 모델 팩토리를 사용하면 Eloquent 모델별 기본 속성값을 미리 정의해 두고 손쉽게 테스트 데이터를 생성할 수 있습니다.
모델 팩토리를 정의하고 활용하는 방법은 모델 팩토리 문서에서 자세히 확인할 수 있습니다. 팩토리를 정의한 후에는 테스트 내에서 다음과 같이 모델을 생성할 수 있습니다.
Pest
use App\Models\User;
test('모델을 생성할 수 있다', function () {
$user = User::factory()->create();
// ...
});PHPUnit
use App\Models\User;
public function test_models_can_be_instantiated(): void
{
$user = User::factory()->create();
// ...
}시더 실행
피처 테스트 중에 데이터베이스 시더를 사용하여 초기 데이터를 채우고 싶다면 seed 메서드를 호출하면 됩니다. 기본적으로 seed 메서드는 DatabaseSeeder를 실행하며, 이를 통해 등록된 모든 시더가 순차적으로 실행됩니다. 특정 시더만 실행하려면 시더 클래스명을 인수로 전달하면 됩니다.
Pest
<?php
use Database\Seeders\OrderStatusSeeder;
use Database\Seeders\TransactionStatusSeeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
pest()->use(RefreshDatabase::class);
test('주문을 생성할 수 있다', function () {
// DatabaseSeeder 전체 실행
$this->seed();
// 특정 시더만 실행
$this->seed(OrderStatusSeeder::class);
// ...
// 여러 시더를 배열로 지정하여 실행
$this->seed([
OrderStatusSeeder::class,
TransactionStatusSeeder::class,
// ...
]);
});PHPUnit
<?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 트레이트를 사용하는 모든 테스트가 시작되기 전에 자동으로 시더를 실행하도록 설정할 수도 있습니다. 기본 테스트 클래스에 #[Seed] 어트리뷰트를 추가하면 됩니다.
<?php
namespace Tests;
use Illuminate\Foundation\Testing\Attributes\Seed;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
#[Seed]
abstract class TestCase extends BaseTestCase
{
}#[Seed] 어트리뷰트가 설정되면 RefreshDatabase 트레이트를 사용하는 각 테스트 실행 전에 Database\Seeders\DatabaseSeeder가 자동으로 실행됩니다. 특정 시더만 실행하고 싶다면 테스트 클래스에 #[Seeder] 어트리뷰트를 사용하면 됩니다.
<?php
namespace Tests\Feature;
use Database\Seeders\OrderStatusSeeder;
use Illuminate\Foundation\Testing\Attributes\Seeder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
#[Seeder(OrderStatusSeeder::class)]
class OrderTest extends TestCase
{
use RefreshDatabase;
// ...
}사용 가능한 어서션
Laravel은 Pest 또는 PHPUnit 피처 테스트에서 사용할 수 있는 다양한 데이터베이스 어서션을 제공합니다. 각 어서션을 아래에서 설명합니다.
assertDatabaseCount
테이블에 지정한 수만큼의 레코드가 있는지 검증합니다.
$this->assertDatabaseCount('users', 5);assertDatabaseEmpty
테이블에 레코드가 하나도 없는지 검증합니다.
$this->assertDatabaseEmpty('users');assertDatabaseHas
테이블에 지정한 키/값 조건에 일치하는 레코드가 존재하는지 검증합니다.
$this->assertDatabaseHas('users', [
'email' => 'sally@example.com',
]);assertDatabaseMissing
테이블에 지정한 키/값 조건에 일치하는 레코드가 존재하지 않는지 검증합니다.
$this->assertDatabaseMissing('users', [
'email' => 'sally@example.com',
]);assertSoftDeleted
지정한 Eloquent 모델이 소프트 삭제되었는지 검증합니다.
$this->assertSoftDeleted($user);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
테스트 시작 시 호출하여 해당 테스트에서 실행될 데이터베이스 쿼리의 총 횟수를 지정합니다. 실제 실행된 쿼리 수가 지정한 값과 다르면 테스트가 실패합니다. 불필요한 쿼리가 발생하지 않는지 확인할 때 유용합니다.
$this->expectsDatabaseQueryCount(5);
// 테스트 코드...