본문 바로가기

데이터베이스 테스트

번역일: 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에 비해 실행 속도가 눈에 띄게 느립니다.

모델 팩토리

테스트를 실행하기 전에 데이터베이스에 샘플 레코드를 넣어야 하는 경우가 많습니다. 이때 컬럼 값을 하나씩 직접 지정하는 대신, 모델 팩토리를 사용하면 각 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, // ... ]); } }

매 테스트마다 시더를 자동으로 실행하고 싶다면, 기본 테스트 클래스에 $seed 프로퍼티를 정의하면 됩니다. RefreshDatabase 트레이트를 사용하는 모든 테스트 전에 시더가 자동으로 실행됩니다.

<?php namespace Tests; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase { /** * 각 테스트 전에 기본 시더를 실행할지 여부 * * @var bool */ protected $seed = true; }

$seedtrue이면 각 테스트 전에 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' => 'sally@example.com', ]);

assertDatabaseMissing

테이블에 주어진 키/값 조건에 맞는 레코드가 존재하지 않는지 확인합니다.

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

assertSoftDeleted

주어진 Eloquent 모델이 소프트 삭제(soft delete) 상태인지 확인합니다.

$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

테스트 중에 실행될 데이터베이스 쿼리의 총 횟수를 미리 지정합니다. 실제 실행된 쿼리 수가 예상값과 다르면 테스트가 실패합니다. N+1 문제 등 불필요한 쿼리 발생을 감지할 때 유용합니다.

$this->expectsDatabaseQueryCount(5); // 테스트 코드...

이 문서는 Laravel 공식 문서(MIT)를 한국 개발자를 위해 번역·재구성한 것입니다.

번역일: 2026년 6월 20일