이종관
글 목록으로

테스트 자동화: 테스트 피라미드부터 카오스 엔지니어링까지

단위/통합/E2E 테스트, 테스트 피라미드, 계약 테스트, 카오스 엔지니어링 실전 가이드

2025년 2월 6일·14 min read·
infra
testing
automation
chaos-engineering
ci-cd

개요

테스트 자동화(Test Automation)는 소프트웨어의 정확성과 안정성을 보장하는 가장 기본적이면서도 핵심적인 엔지니어링 실천이다. 수동 테스트에 의존하는 조직은 배포 속도가 느리고, 회귀 버그(Regression Bug)에 취약하며, 장기적으로 기술 부채(Technical Debt)가 누적된다.

2026년 현재, AI 기반 테스트 생성이 주류로 진입하면서 테스트 자동화의 패러다임이 근본적으로 변화하고 있다. Gartner는 2026년까지 40%의 QA 팀이 모델 검증 프레임워크를 도입할 것으로 전망한다.

테스트 수준 (Test Levels)

1. 단위 테스트 (Unit Test)

개별 함수, 메서드, 모듈을 격리된 환경에서 검증하는 가장 작은 단위의 테스트이다.

특징:

  • 가장 빠른 피드백 루프 (밀리초 단위 실행)
  • 외부 의존성은 모킹(Mocking)이나 스터빙(Stubbing)으로 대체
  • 높은 커버리지 달성이 용이
  • 리팩터링 시 안전망 역할

예시 (Jest):

javascript
describe('calculateDiscount', () => {
  it('10% 할인을 올바르게 계산한다', () => {
    const result = calculateDiscount(10000, 0.1);
    expect(result).toBe(9000);
  });
 
  it('할인율이 0이면 원래 가격을 반환한다', () => {
    const result = calculateDiscount(10000, 0);
    expect(result).toBe(10000);
  });
 
  it('음수 할인율에 대해 에러를 던진다', () => {
    expect(() => calculateDiscount(10000, -0.1)).toThrow();
  });
});

TDD (Test-Driven Development) 방법론:

  1. RED: 실패하는 테스트를 먼저 작성
  2. GREEN: 테스트를 통과시키는 최소한의 코드 작성
  3. REFACTOR: 코드를 개선하면서 테스트가 계속 통과하는지 확인

2. 통합 테스트 (Integration Test)

여러 모듈이 함께 동작할 때의 상호작용을 검증한다. 데이터베이스, 외부 API, 메시지 큐 등 실제 인프라와의 연동을 테스트한다.

검증 범위:

  • 데이터베이스 CRUD 연산의 정합성
  • 외부 API 호출 및 응답 처리
  • 메시지 큐(Kafka, RabbitMQ) 연동
  • 캐시(Redis) 동작 확인
  • 트랜잭션 경계(Transaction Boundary) 검증

Testcontainers 활용:

Testcontainers는 Docker 컨테이너를 활용하여 테스트 시 실제 데이터베이스, 메시지 브로커 등을 일시적으로 구동하는 라이브러리이다. 목(Mock) 대신 실제 인프라를 사용하므로 테스트 신뢰도가 높아진다.

java
@Testcontainers
class UserRepositoryTest {
    @Container
    static PostgreSQLContainer<?> postgres =
        new PostgreSQLContainer<>("postgres:16-alpine");
 
    @Test
    void 사용자_저장_및_조회가_올바르게_동작한다() {
        UserRepository repo = new UserRepository(postgres.getJdbcUrl());
        User user = new User("test@example.com", "홍길동");
 
        repo.save(user);
        User found = repo.findByEmail("test@example.com");
 
        assertThat(found.getName()).isEqualTo("홍길동");
    }
}

3. E2E 테스트 (End-to-End Test)

사용자의 전체 시나리오를 시뮬레이션하여 시스템의 끝단(End-to-End) 동작을 검증한다.

특징:

  • 가장 느리고 비용이 높지만, 실제 사용자 경험에 가장 가까운 테스트
  • 브라우저 자동화(Playwright, Cypress) 또는 API 수준에서 수행
  • 핵심 비즈니스 플로우에 집중하여 최소한으로 유지

Playwright 예시:

typescript
test('사용자가 상품을 검색하고 장바구니에 추가할 수 있다', async ({ page }) => {
  await page.goto('https://shop.example.com');
  await page.fill('[data-testid="search-input"]', '노트북');
  await page.click('[data-testid="search-button"]');
 
  await expect(page.locator('.product-card')).toHaveCount.greaterThan(0);
 
  await page.click('.product-card:first-child [data-testid="add-to-cart"]');
  await expect(page.locator('[data-testid="cart-count"]')).toHaveText('1');
});

테스트 전략 모델

테스트 피라미드 (Test Pyramid)

Martin Fowler가 제안한 전통적 모델로, 아래에서 위로 갈수록 테스트 수가 줄어든다.

plaintext
        /  E2E  \          ← 소수 (느림, 비쌈)
       /Integration\       ← 적당량
      / Unit Tests  \      ← 다수 (빠름, 저렴)
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾

테스팅 트로피 (Testing Trophy)

Kent C. Dodds가 제안한 현대적 모델로, 통합 테스트를 가장 많이 작성할 것을 권장한다.

plaintext
        /   E2E   \
       / Integration\      ← 가장 많이 (비용 대비 효과 최적)
      /   Unit Tests  \
     /  Static Analysis \  ← TypeScript, ESLint 등
     ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
모델핵심 주장적합한 환경
테스트 피라미드Unit 테스트 최다순수 로직이 많은 라이브러리
테스팅 트로피Integration 테스트 최다웹 애플리케이션, API 서버

고급 테스트 기법

계약 테스트 (Contract Testing)

마이크로서비스 간의 API 계약(Contract)을 검증하는 테스트이다. 서비스 제공자(Provider)와 소비자(Consumer) 양측이 합의한 인터페이스를 위반하지 않는지 확인한다.

Pact 프레임워크:

  • Consumer가 기대하는 요청/응답 쌍을 "Pact 파일"로 정의
  • Provider가 Pact 파일을 기반으로 자동 검증
  • Pact Broker를 통해 계약을 중앙에서 관리
plaintext
Consumer A ──(Pact 파일)──→ Pact Broker ──→ Provider B

                                    자동 검증 실행

돌연변이 테스트 (Mutation Testing)

소스 코드에 **의도적인 결함(Mutant)**을 주입하고, 기존 테스트가 이를 탐지하는지 확인하여 테스트 스위트의 품질을 측정한다.

돌연변이 유형:

  • 조건 변이: >>=, ==!=
  • 산술 변이: +-, */
  • 반환값 변이: return truereturn false
  • 제거 변이: 특정 문장 삭제

도구: Stryker (JavaScript/TypeScript), PITest (Java), mutmut (Python)

돌연변이 점수(Mutation Score):

plaintext
돌연변이 점수 = (죽은 돌연변이 수 / 전체 돌연변이 수) * 100%

80% 이상이면 테스트 스위트가 양호하다고 판단한다.

속성 기반 테스트 (Property-Based Testing)

특정 입력값 대신 **속성(Property)**을 정의하고, 프레임워크가 수천 개의 무작위 입력을 생성하여 속성이 항상 성립하는지 검증한다.

typescript
// fast-check 라이브러리 예시
import fc from 'fast-check';
 
test('정렬 함수는 항상 정렬된 배열을 반환한다', () => {
  fc.assert(
    fc.property(fc.array(fc.integer()), (arr) => {
      const sorted = mySort(arr);
      for (let i = 1; i < sorted.length; i++) {
        expect(sorted[i]).toBeGreaterThanOrEqual(sorted[i - 1]);
      }
    })
  );
});

장점: 개발자가 미처 생각하지 못한 엣지 케이스를 자동으로 발견

스냅샷 테스트 (Snapshot Testing)

컴포넌트의 렌더링 결과나 API 응답을 스냅샷 파일로 저장하고, 이후 변경 사항이 발생하면 차이를 보고한다.

적합한 대상:

  • React 컴포넌트의 렌더링 결과
  • API 응답 JSON 구조
  • 설정 파일 생성 결과

주의점: 스냅샷이 너무 크거나 자주 변경되면 유지보수 비용이 증가한다. 핵심 구조만 캡처하는 것이 권장된다.

카오스 엔지니어링 (Chaos Engineering)

개념

프로덕션 환경 또는 유사 환경에서 의도적으로 장애를 주입하여 시스템의 복원력(Resilience)을 검증하는 방법론이다. Netflix의 Chaos Monkey에서 시작되어, 현재는 다양한 도구와 프레임워크로 발전했다.

카오스 엔지니어링의 원칙

  1. 정상 상태 가설 수립: 시스템의 정상 동작을 정의
  2. 실험 변수 도입: 서버 장애, 네트워크 지연, 디스크 고갈 등
  3. 통제 그룹과 실험 그룹 비교: A/B 형태로 영향도 측정
  4. 폭발 반경(Blast Radius) 최소화: 점진적 확대

주요 도구

도구특징환경
Chaos MonkeyNetflix OSS, 랜덤 인스턴스 종료AWS
LitmusKubernetes 네이티브 카오스Kubernetes
Chaos Toolkit선언적 카오스 실험 정의범용
Gremlin엔터프라이즈급 SaaS범용
Steadybit팀 협업 기반 신뢰성 테스트Kubernetes/클라우드

AI 기반 카오스 테스트 (2026 최신)

Uber는 LLM 기반 모바일 테스트 플랫폼(DragonCrawl)과 서비스 레벨 장애 주입 시스템(uHavoc)을 통합하여, 2024년 Q1 이후 47개 핵심 플로우에서 180,000건 이상의 자동화된 카오스 테스트를 실행했다. 이는 약 39,000시간의 수동 테스트에 해당한다.

Red Hat과 IBM Research 팀은 AI를 Krkn(카오스 엔지니어링 프레임워크)에 통합하여, Prometheus 메트릭을 기반으로 각 Pod의 리소스 프로필을 분석하고 가장 높은 중단 확률을 가진 시나리오를 자동 추천하는 chaos-recommender를 개발했다.

Shift-Left 테스팅

테스트를 개발 주기의 **왼쪽(초기 단계)**으로 이동시키는 전략이다.

plaintext
전통적:  설계 → 개발 → ──────── 테스트 → 배포
Shift-Left: 설계+테스트 → 개발+테스트 → 테스트 → 배포

Shift-Left 실천 방법

  1. 정적 분석 (Static Analysis): TypeScript, ESLint, SonarQube로 코드 작성 시점에 문제 탐지
  2. Pre-commit Hooks: husky + lint-staged로 커밋 전 자동 검사
  3. PR 단계 자동 테스트: GitHub Actions에서 모든 PR에 대해 테스트 실행
  4. 보안 스캔 (SAST): Snyk, Semgrep으로 취약점 조기 발견

AI 기반 테스트 생성 (2026 트렌드)

현황

AI가 테스트 생성, 플레이크 탐지(Flake Detection), 셀렉터 자동 수정(Self-Healing Selectors)을 자동화하고 있다. AI 테스트 도입 팀은 32% 빠른 릴리스 사이클25% 낮은 결함 유출률을 보고한다.

주요 도구 (2026)

도구기능특징
TestimAI 기반 E2E 테스트 자동 생성Self-healing 셀렉터
Mabl지능형 테스트 자동화자동 결함 탐지
Diffblue CoverJava 단위 테스트 자동 생성AI 기반 코드 분석
Codium AILLM 기반 테스트 생성코드 컨텍스트 이해
testRigor자연어 기반 테스트 작성비개발자도 테스트 작성 가능

AI가 AI를 테스트하다

2026년에는 "AI가 AI를 테스트하는" 패러다임이 주류로 진입하고 있다:

  • 합성 데이터 생성 (Synthetic Data Generation): 테스트용 데이터 자동 생성
  • 편향 탐지 (Bias Detection): ML 모델의 편향을 자동으로 식별
  • 설명 가능성 테스트 (Explainability Testing): 모델 결정의 해석 가능성 검증

테스트 자동화 모범 사례

CI/CD 파이프라인 통합

yaml
# GitHub Actions 예시
test:
  runs-on: ubuntu-latest
  steps:
    - name: Unit Tests
      run: npm run test:unit -- --coverage
    - name: Integration Tests
      run: npm run test:integration
    - name: E2E Tests (핵심 플로우만)
      run: npx playwright test --project=critical
    - name: Mutation Testing (주간)
      if: github.event.schedule
      run: npx stryker run

테스트 커버리지 가이드라인

지표목표비고
라인 커버리지80% 이상최소 기준
브랜치 커버리지70% 이상조건문 분기 검증
돌연변이 점수80% 이상테스트 품질 검증
E2E 커버리지핵심 플로우 100%비즈니스 크리티컬 경로

테스트 작성 원칙

  1. FIRST 원칙: Fast, Isolated, Repeatable, Self-validating, Timely
  2. AAA 패턴: Arrange(준비) → Act(실행) → Assert(검증)
  3. 한 테스트에 한 가지 검증: 실패 시 원인을 즉시 파악 가능
  4. 테스트 이름으로 의도 표현: 사용자가_존재하지_않으면_404를_반환한다

참고 자료