본문으로 건너뛰기

테스트 전략 개요

Multi-SaaS Kit의 테스트 시스템과 전략을 소개합니다.

개요

Multi-SaaS Kit은 448개 테스트, 1,042개 assertion으로 구성된 견고한 테스트 시스템을 갖추고 있습니다. PHPUnit과 Pest 기반으로 작성되어 있으며, Core 모듈에 대해서는 TDD 접근법을 적용합니다.

┌─────────────────────────────────────────────────────────────┐
│ 테스트 피라미드 │
│ │
│ /\ │
│ / \ E2E 테스트 (선택) │
│ /----\ │
│ / \ │
│ / \ Feature 테스트 (통합) │
│ /----------\ │
│ / \ │
│ / \ Unit 테스트 (단위) │
│ /----------------\ │
│ │
│ Unit : Feature = 7 : 3 비율 권장 │
└─────────────────────────────────────────────────────────────┘

테스트 스택

도구역할
PHPUnit테스트 프레임워크
PestPHPUnit 래퍼 (간결한 문법)
SQLite In-Memory테스트 데이터베이스
Factory테스트 데이터 생성
RefreshDatabase테스트 간 DB 초기화
테스트 DB 분리

RefreshDatabase는 PHPUnit 실행 중 APP_ENV=testing에서 내부적으로 migrate:fresh를 호출할 수 있습니다. MSK의 DB 안전 가드는 이 테스트 러너 경로만 허용하므로, phpunit.xmltests/TestCase에서 운영 DB가 아닌 별도 테스트 DB 또는 SQLite in-memory를 사용하도록 반드시 고정해야 합니다.

테스트 현황

영역테스트 수Assertions설명
Core/Permission1545권한 시스템 (Level 0~6, ADR-058)
Core/Tenant1751테넌트 격리
Core/Guardian72216후견인 관계 (Extension)
Core/Impersonate66198사용자 전환 (Extension)
Models81243User, Tenant, Organization
Seeder39117CoreSeeder 검증
Filament41123Admin Panel 기능
Security824Cross-Tenant 보안
Total4481,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()

Pest 스타일

test('사용자는 구독 상태를 확인할 수 있다', function () {
// ...
});

it('만료된 구독은 false를 반환한다', function () {
// ...
});

CI/CD 통합

GitHub Actions 예시

name: Tests

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
coverage: xdebug

- name: Install Dependencies
run: composer install --no-interaction

- name: Run Tests
run: php artisan test --parallel

관련 문서