우아한 PHP Test Framework Pest - #2 Test 작성
PHPStorm 이나 VSCode 용 Pest plugin 을 설치하세요.
Pest 는 단위 테스트를 간략하게 작성할 수 있도록 도와주며 laravel 의 test 폴더 구조에 맞게 Unit 과 Feature 에 있는 Test.php 로 끝나는 모든 클래스를 자동으로 실행합니다.
tests - Unit - ComponentTest.php -- 유닛 테스트 클래스 - Feature - HomeTest.php -- 피처 테스트 클래스 Pest.php -- Pest 부트스트랩 phpunit.xml
이제 실제 테스트 케이스 작성을 위해 다음 artisan 명령으로 테스트 클래스를 생성합니다.
$ php artisan make:test ComponentTest --unit
$ php artisan make:test HomeTest
Pest 를 사용하면 기존의 TestCase 를 상속받지 않고 다음과 같이 test() 나 it() 메서드로 간략하게 테스트를 작성할 수 있습니다.
<?php test('has home', function () { $this->assertTrue(true); }); // 또는 it('has home', function () { $this->assertTrue(true); });
테스트 함수 작성 - test() 와 it()
test() 함수의 첫 번째 파라미터는 test 에 대한 설명, 2번째는 클로저입니다.
<?php function test(string $description = null, Closure $closure = null) {
it() 도 마찬가지이며 차이점은 $description 앞에 "it" 이라는 단어를 추가해서 실행한다는 점입니다.
<?php function it(string $description = null, Closure $closure = null) {
<?php test('has home', function () { $this->assertTrue(true); }); // 또는 it('has home', function () { $this->assertTrue(true); });
HomeTest.php 에 작성한 테스트를 실행하면 다음과 같은 결과를 표시하며 it() 의 경우 description 에 it 이라는 문자열을 추가한 것을 확인할 수 있습니다.
./vendor/bin/pest
테스트 케이스에 바인딩 - uses()
테스트 케이스에서 특정 클래스나 trait 이 필요할 수 있습니다. 예로 Database 테스트가 끝난 후에 RefreshDatabase trait 을 사용해서 테스트 데이타를 지워야 합니다.
이럴 경우 클래스나 trait 을 현재 테스트 케이스에 바인딩 해주는 uses() 함수를 사용하면 됩니다.
<?php use App\Models\User; use \Illuminate\Foundation\Testing\WithFaker; use \Illuminate\Foundation\Testing\RefreshDatabase; // 테스크 케이스에 trait 바인딩 uses(WithFaker::class); uses(RefreshDatabase::class); test('has user', function () { $faker = $this->faker('ko_KR'); $u = User::create([ 'name' => $faker->name, 'email' => $faker->email, 'password' => bcrypt('secret'), ]); $this->assertDatabaseHas('users', [ 'email' => $u->email, ]); });
이제 pest 를 실행하면 단위 테스트를 실행하고 테스트 데이타를 삭제한 것을 확인할 수 있습니다.
./vendor/bin/pest PASS Tests\Unit\ComponentTest ✓ example PASS Tests\Unit\ExampleTest ✓ basic test PASS Tests\Feature\ExampleTest ✓ basic test PASS Tests\Feature\HomeTest ✓ has user Tests: 4 passed Time: 1.16s
하위 폴더에도 바인딩 - in()
RefreshDatabase 처럼 여러 테스트 케이스에서 사용할 trait 을 매번 지정하는 건 번거로운 일입니다. 이런 불편을 해결하려면 Pest 의 Boot strap 파일인 Pest.php 에 uses() 함수를 옮기면 됩니다.
<?php uses(Tests\TestCase::class)->in('Feature'); // 테스크 케이스에 trait 바인딩 uses(\Illuminate\Foundation\Testing\WithFaker::class); uses(\Illuminate\Foundation\Testing\RefreshDatabase::class);
<?php use App\Models\User; test('has user', function () { $faker = $this->faker('ko_KR'); $u = User::create([ 'name' => $faker->name, 'email' => $faker->email, 'password' => bcrypt('secret'), ]); $this->assertDatabaseHas('users', [ 'email' => $u->email, ]); });
이제 Pest 를 실행하면 다음과 같이 에러가 발생합니다.
./vendor/bin/pest
이는 Feature 는 하위 폴더이므로 uses() 로 바인딩해도 영향을 주지 않아서이며 in() 함수로 하위 폴더까지 바인딩하도록 선언해야 합니다.
Pest.php 를 아래와 같이 in() 을 호출하도록 수정하고 다시 실행하면 정상 동작하는 것을 확인할 수 있습니다.
<?php uses(Tests\TestCase::class)->in('Feature'); // 테스크 케이스에 trait 바인딩 uses(\Illuminate\Foundation\Testing\WithFaker::class)->in('Feature'); uses(\Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature');
만약 Unit 하위 폴더에도 바인딩할 경우 in() 을 별도로 호출해 주면 됩니다.
<?php uses(Tests\TestCase::class)->in('Feature'); // 테스크 케이스에 trait 바인딩 uses(\Illuminate\Foundation\Testing\WithFaker::class)->in('Feature'); uses(\Illuminate\Foundation\Testing\WithFaker::class)->in('Unit'); uses(\Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Feature'); uses(\Illuminate\Foundation\Testing\RefreshDatabase::class)->in('Unit');
또는 uses() 의 첫 번째 함수에 바인딩할 trait 이름을 배열로 넘기면 더 깔끔하게 작성할 수 있습니다.
<?php use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; uses(Tests\TestCase::class)->in('Feature'); // 테스크 케이스에 trait 바인딩 uses(WithFaker::class, RefreshDatabase::class)->in('Feature'); uses(WithFaker::class, RefreshDatabase::class)->in('Unit');