안정적인 프로덕션 애플리케이션을 유지하고 지속적 통합(CI)을 구축하려면 테스트 자동화가 필수입니다. PHP 진영의 표준 테스트 프레임워크인 PHPUnit을 활용하여, Slim의 라우터 엔드포인트에 가상(Mock) 요청을 밀어넣고 그 응답(Response)이 의도한 대로 동작하는지 검증하는 방법을 알아봅니다.
먼저 컴포저를 통해 require --dev phpunit/phpunit 명령어로 개발 환경용 패키지를 설치합니다. 이후 프로젝트 루트에 phpunit.xml 설정 파일을 생성하여 테스트 대상 디렉터리와 환경 변수를 세팅합니다.
<!-- phpunit.xml 설정 예시 -->
<phpunit bootstrap="vendor/autoload.php" colors="true">
<testsuites>
<testsuite name="Slim Application Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<php>
<!-- 테스트 전용 환경 변수(DB 등) 오버라이딩 가능 -->
<env name="APP_ENV" value="testing"/>
</php>
</phpunit>
Slim 앱을 테스트할 때는 실제 서버(Apache/Nginx)를 띄우거나 Postman을 사용할 필요가 없습니다. 대신, 코드 상에서 가짜(Mock) PSR-7 Request 객체를 생성하여 Slim의 $app->handle($request) 코어 메서드에 직접 주입(Inject)하고, 그 결과로 튀어나오는 Response 객체를 검사하는 '인메모리(In-Memory) 테스트' 방식을 사용합니다.
| 주요 Assertion (검증) 메서드 | 동작 원리 및 사용처 |
|---|---|
assertSame($expected, $actual) |
HTTP 상태 코드(200, 404 등)나 헤더 값이 기대한 것과 정확히 일치(===)하는지 엄격하게 검사합니다. |
assertJson($string) |
응답 바디 문자열이 문법적으로 유효한 JSON 포맷인지 확인합니다. API 테스트에 필수입니다. |
assertStringContainsString() |
응답 바디(문자열) 내에 특정 에러 메시지나 성공 키워드가 포함되어 있는지 느슨하게 검사합니다. |
tests/UserApiTest.php 파일을 생성하고, PHPUnitFrameworkTestCase를 상속받는 테스트 클래스를 작성합니다. 모든 테스트 케이스 메서드 이름은 반드시 test로 시작해야 인식됩니다.
<?php
use PHPUnit\Framework\TestCase;
use Slim\Factory\AppFactory;
use Slim\Psr7\Factory\ServerRequestFactory;
class UserApiTest extends TestCase
{
// 테스트용 Slim App 인스턴스를 메모리에 생성하는 헬퍼 메서드
protected function getApp() {
$app = AppFactory::create();
// 실제로는 require 'routes.php'; 로 가져옵니다.
$app->get('/api/users', function ($req, $res) {
$res->getBody()->write(json_encode(['status' => 'success']));
return $res->withHeader('Content-Type', 'application/json')->withStatus(200);
});
return $app;
}
public function testGetUsersReturnsSuccess()
{
$app = $this->getApp();
// 1. Arrange (준비): 가짜(Mock) GET /api/users PSR-7 요청 객체 생성
$requestFactory = new ServerRequestFactory();
$request = $requestFactory->createServerRequest('GET', '/api/users');
// 2. Act (실행): 애플리케이션 코어에 가짜 요청을 밀어넣고 결과 응답 획득
$response = $app->handle($request);
// 3. Assert (검증): 예상된 결과와 실제 결과 비교
$this->assertSame(200, $response->getStatusCode());
$body = (string) $response->getBody();
$this->assertJson($body);
$this->assertStringContainsString('success', $body);
}
}
터미널에서 ./vendor/bin/phpunit 명령을 실행하면, tests/ 디렉터리 내의 모든 테스트 코드를 자동으로 찾아 실행합니다. 테스트가 모두 통과하면 초록색 OK 메시지가, 단 하나라도 실패하면 빨간색 FAILURES 메시지와 실패 원인이 출력됩니다.
하단의 시뮬레이터 버튼을 눌러, 실제 개발 환경의 터미널(bash)에서 PHPUnit이 실행될 때 테스트 결과(성공 시의 쾌감과 실패 시의 에러 추적)가 콘솔에 어떻게 출력되는지 체험해 보세요.