테스트 전략 개요
Multi-SaaS Kit의 테스트 시스템과 전략을 소개합니다.
개요
Multi-SaaS Kit은 448개 테스트, 1,042개 assertion으로 구성된 견고한 테스트 시스템을 갖추고 있습니다. PHPUnit과 Pest 기반으로 작성되어 있으며, Core 모듈에 대해서는 TDD 접근법을 적용합니다.
┌─────────────────────────────────────────────────────────────┐
│ 테스트 피라미드 │
│ │
│ /\ │
│ / \ E2E 테스트 (선택) │
│ /----\ │
│ / \ │
│ / \ Feature 테스트 (통합) │
│ /----------\ │
│ / \ │
│ / \ Unit 테스트 (단위) │
│ /----------------\ │
│ │
│ Unit : Feature = 7 : 3 비율 권장 │
└─────────────────────────────────────────────────────────────┘
테스트 스택
| 도구 | 역할 |
|---|---|
| PHPUnit | 테스트 프레임워크 |
| Pest | PHPUnit 래퍼 (간결한 문법) |
| SQLite In-Memory | 테스트 데이터베이스 |
| Factory | 테스트 데이터 생성 |
| RefreshDatabase | 테스트 간 DB 초기화 |
테스트 DB 분리
RefreshDatabase는 PHPUnit 실행 중 APP_ENV=testing에서 내부적으로 migrate:fresh를 호출할 수 있습니다. MSK의 DB 안전 가드는 이 테스트 러너 경로만 허용하므로, phpunit.xml과 tests/TestCase에서 운영 DB가 아닌 별도 테스트 DB 또는 SQLite in-memory를 사용하도록 반드시 고정해야 합니다.
테스트 현황
| 영역 | 테스트 수 | Assertions | 설명 |
|---|---|---|---|
| Core/Permission | 15 | 45 | 권한 시스템 (Level 0~6, ADR-058) |
| Core/Tenant | 17 | 51 | 테넌트 격리 |
| Core/Guardian | 72 | 216 | 후견인 관계 (Extension) |
| Core/Impersonate | 66 | 198 | 사용자 전환 (Extension) |
| Models | 81 | 243 | User, Tenant, Organization |
| Seeder | 39 | 117 | CoreSeeder 검증 |
| Filament | 41 | 123 | Admin Panel 기능 |
| Security | 8 | 24 | Cross-Tenant 보안 |
| Total | 448 | 1,042 | - |
테스트 분류
Unit 테스트
단일 클래스/메서드를 격리하여 테스트합니다.
tests/Unit/
├── Core/
│ ├── Permission/ # 권한 로직
│ ├── Tenant/ # 테넌트 스코프
│ ├── Guardian/ # 후견인 관계
│ └── Impersonate/ # 사용자 전환
├── Models/ # 모델 로직
└── Services/ # 서비스 로직
Feature 테스트
여러 컴포넌트 를 통합하여 테스트합니다.
tests/Feature/
├── Core/
│ └── Security/ # Cross-Tenant 보안
├── Filament/ # Admin Panel
├── Http/ # API 엔드포인트
└── Seeder/ # CoreSeeder 검증
테스트 환경 설정
phpunit.xml
<phpunit>
<php>
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
</php>
</phpunit>
TestCase 기본 설정
// tests/TestCase.php
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
// 테넌트 기능 비활성화 (Unit 테스트)
config(['core.tenant.enabled' => false]);
}
}
테스트 실행
전체 테스트
# 모든 테스트 실행
php artisan test
# 또는 Pest 직접 실행
./vendor/bin/pest
특정 테스트 실행
# 특정 파일
php artisan test tests/Unit/Core/Permission/HasLevelTest.php
# 특정 폴더
php artisan test tests/Unit/Core/
# 특정 메서드 (필터)
php artisan test --filter=test_user_can_check_level
# 그룹별 실행
php artisan test --group=permission
병렬 실행
# 병렬 테스트 (빠름)
php artisan test --parallel
# 프로세스 수 지정
php artisan test --parallel --processes=4
커버리지 확인
# HTML 리포트 생성
php artisan test --coverage-html reports/coverage
# 콘솔 요약
php artisan test --coverage
TDD 적용 원칙
Multi-SaaS Kit은 Core 모듈에 대해 **TDD (Test-Driven Development)**를 적용합니다.
TDD 필수 영역
| 영역 | 이유 |
|---|---|
| Core/Permission | 권한 오류 = 보안 사고 |
| Core/Tenant | 데이터 격리 = SaaS 핵심 |
| Core/Audit | 감사 로그 무결성 |
| 비즈니스 로직 | 계산, 상태 전이 |
| 보안 관련 | 인증, 인가 |
TDD 워크플로우
1. 실패하는 테스트 작성 (Red)
↓
2. 테스트를 통과하는 최소 코드 작성 (Green)
↓
3. 코드 리팩토링 (Refactor)
↓
4. 반복
테스트 헬퍼
CreatesTestTenant
테넌트 관련 테스트를 위한 Trait:
use Tests\Traits\CreatesTestTenant;
class MyTest extends TestCase
{
use CreatesTestTenant;
public function test_example(): void
{
// Tenant Admin으로 로그인
$user = $this->actAsTenantAdmin();
// 특정 테넌트 컨텍스트 설정
$this->setTenantContext($tenant);
}
}
Factory 사용
// 기본 사용자
$user = User::factory()->create();
// 특정 레벨 사용자
$admin = User::factory()->create(['level' => 0]);
// 테넌트와 함께
$tenant = Tenant::factory()
->has(User::factory()->count(3))
->create();
명명 규칙
테스트 파일
{테스트대상}Test.php
예:
HasLevelTest.php
TenantScopeTest.php
UserResourceTest.php
테스트 메서드
// 형식: test_{feature}_{scenario}_{expected_outcome}
test_user_can_check_subscription_status()
test_expired_subscription_returns_false()
test_tenant_user_cannot_see_other_tenant_data()