infra
Platform

모듈 맵

[SW Eng] 테스트 전략 — 피라미드·커버리지·QA의 역할

0 / 38 완료

펼치기
0 / 38 완료0%

Sw-engineering · 22 / 38

[SW Eng] 테스트 전략 — 피라미드·커버리지·QA의 역할

단위/통합/E2E 테스트 피라미드, 커버리지의 의미와 함정, 회귀·스모크 테스트와 QA 프로세스를 PM·인프라 관점에서 정리합니다

🚨INCIDENT ALERT
HIGH

배포 때마다 가슴이 조마조마합니다. "이거 올리면 다른 데 안 깨질까요?" 아무도 확신 못 합니다. 지난번 결제 버그를 고쳤는데 한 달 뒤 똑같은 버그가 다시 났습니다. 한편 QA팀은 "테스트 커버리지 80% 달성!"을 자랑하는데, 정작 결제 핵심 흐름은 한 번도 단언(assert) 없이 '실행만' 되고 있었습니다. 테스트는 '품질을 비싸게 사는 보험'이 아니라, 변경을 두려움 없이 자주 할 수 있게 하는 속도의 기반입니다. 단, 잘못 쌓으면 느리고 거짓 신뢰만 줍니다.

이번 챕터에서 배울 것
  • 1테스트 피라미드(단위>통합>E2E)의 비율과 이유를 설명할 수 있다
  • 2커버리지 숫자의 의미와 함정(실행≠검증)을 설명할 수 있다
  • 3스모크·회귀 테스트가 각각 무엇을 막는지 구분할 수 있다
  • 4CI 자동 테스트와 QA 수동 검증의 역할 분담을 설명할 수 있다

테스트 피라미드

💡개념

빠르고 싼 것을 많이, 느리고 비싼 것을 적게

TEXT
        /\        E2E (적게)  — 실제 사용자 흐름 전체. 느리고 깨지기 쉬움(flaky)
       /  \       통합 (중간) — 모듈·외부(DB/API) 연동 검증
      /____\      단위 (많이) — 함수/클래스 단위. 빠르고 싸고 안정적

피드백 속도:  단위(ms) > 통합(초) > E2E(분)
유지 비용:    단위(낮음) < 통합 < E2E(높음, UI 바뀌면 깨짐)

핵심: 빠른 피드백([[cicd-pipeline]]의 fail-fast)은 단위 테스트에서 옵니다. E2E를 너무 많이 쌓으면(역피라미드) 파이프라인이 느려지고 flaky(간헐 실패)해져, 팀이 빨간불을 무시하기 시작합니다. E2E는 '가장 중요한 몇 개 흐름'만 핵심으로 둡니다.

커버리지의 진실 — 실행 ≠ 검증

💡개념

80%라는 숫자가 속이는 것

커버리지는 '테스트가 실행한 코드 비율'입니다. 함정이 둘입니다.

TEXT
함정 1: 실행만 하고 단언(assert) 안 함
  test("결제", () => { pay(1000); });        // 호출만, 결과 검증 없음
  → 커버리지엔 잡히지만(실행됨) 버그는 못 잡음(틀려도 통과)

함정 2: 숫자 채우기
  중요한 결제·인증은 안 짜고, 쉬운 getter/setter로 80% 채움
  → 정작 위험한 곳은 미검증

올바른 관점: 커버리지는 참고 지표일 뿐입니다. 중요한 것은 **"위험한 흐름(결제·인증·데이터 정합)이 의미 있게 검증되는가"**입니다. 커버리지 목표를 KPI로 강제하면 '숫자 채우기'라는 [[tech-debt-refactoring]] 성격의 부작용이 생깁니다. PM은 "커버리지 몇 %"가 아니라 "핵심 시나리오([[requirements-prd]]의 인수기준)가 테스트로 있는가"를 물어야 합니다.

어떤 테스트를 언제
함수/로직의 정확성을 빠르게 검증단위 테스트가장 많이, CI 매번
DB·외부 API 연동이 맞물려 동작하는지통합 테스트중간 수, 주요 연동
사용자 핵심 흐름 전체(로그인→결제)E2E(소수)느림, 핵심만
배포 직후 '살아있나' 1차 확인스모크 테스트빠름, 모든 배포에
고친 버그·기존 기능 보호회귀 테스트버그 케이스를 테스트로 박제

핵심 흐름 검증 점검 — 직접 확인

1커버리지 숫자가 아니라 '핵심 흐름 검증'을 점검

PM·QA·인프라는 '커버리지 %'가 아니라 '위험한 흐름이 테스트로 보호되는가'를 점검합니다.

TEXT
핵심 시나리오 ↔ 테스트 매핑:
  결제 성공                → 단위✓ 통합✓ E2E✓
  결제 실패 재시도         → 단위✓ 통합✗  ← 빠짐! 위험
  중복 결제 방지(멱등)      → 단위✗        ← 빠짐! 사고 직결
  로그인/권한              → 단위✓ E2E✓
  → 커버리지는 80%여도 '결제 실패·중복'이 미검증이면 실질 리스크 높음

배포 게이트:
  □ 스모크 테스트가 핵심 경로(홈/로그인/결제시작)를 커버하나?
  □ 과거 장애가 회귀 테스트로 박제됐나?
OUTPUT
점검 결과:
  커버리지 82% (양호해 보임)
  그러나 '중복 결제 방지' 테스트 없음 → 가장 비싼 사고가 미검증
→ 숫자보다 "어떤 흐름이 검증되나"가 중요. 결제 예외/중복부터 보강
echo '인수기준 → 대응 테스트 존재 여부 매핑'
🔍실행 후 확인할 것
  • 커버리지 숫자보다 "핵심 시나리오(결제·인증·중복방지)에 대응 테스트가 있나"를 먼저 본다 — 80%여도 위험 흐름이 비면 실질 리스크 큼
  • 테스트가 호출만 하고 단언(expect/assert)이 없으면 커버리지엔 잡혀도 버그는 못 잡음 → "검증의 질"을 확인
  • E2E 테스트가 자주 깨지면(flaky) 팀이 빨간불을 무시 → 신뢰 붕괴([[cicd-pipeline]]). E2E는 핵심 소수만, 단위로 무게중심 이동
  • 과거 장애가 회귀 테스트로 박제됐는지 확인 — 안 됐으면 같은 버그가 재발 가능. 장애 포스트모템([[slo-error-budget]])의 액션으로 테스트 추가

상황: "커버리지 80% 달성"을 목표로 테스트를 늘렸는데, 쉬운 코드 위주로 숫자를 채우고 정작 결제의 중복 방지(멱등) 로직은 테스트가 없었습니다. 결국 [[async-event-driven]]의 메시지 중복 상황에서 중복 결제 사고가 터집니다.

원인: 커버리지 숫자를 목표로 삼아 검증의 질이 아니라 양을 좇았습니다. 가장 위험한 흐름(돈이 걸린 결제·중복)이 미검증으로 남았습니다.

진단:

TEXT
□ 결제 성공/실패/중복/환불 각각에 단언이 있는 테스트가 있나?
□ 과거 발생한 결제 사고가 회귀 테스트로 박제됐나?
□ 커버리지 높은 영역이 '쉬운 코드'에 쏠려 있지 않나?

해결: (1) 커버리지를 KPI에서 '참고 지표'로 강등하고, 위험 기반 테스트(돈·인증·데이터 정합 흐름 우선)로 전환. (2) 모든 장애는 [[slo-error-budget]]의 포스트모템에서 회귀 테스트로 박제 — 같은 버그 재발을 CI가 막게. (3) 결제 같은 핵심은 인수기준([[requirements-prd]])의 정상·예외·경계가 모두 테스트로 존재하는지 확인. 테스트의 가치는 줄 수가 아니라 '무엇을 보호하는가'에 있습니다.

💼
실무 맥락
현업 패턴

인프라/SRE로서 테스트 전략은 [[cicd-pipeline]] 게이트의 품질을 결정합니다 — 단위 테스트로 빠른 피드백을, 스모크 테스트로 배포 직후 핵심 경로 생존을, 회귀 테스트로 과거 장애 재발 방지를 보장합니다. flaky E2E를 격리해 파이프라인 신뢰를 지키는 것도 플랫폼팀의 일입니다. PM은 "커버리지 몇 %"가 아니라 "결제·인증 같은 핵심 시나리오가 테스트로 보호되는가"를 품질 기준으로 삼고, 모든 장애의 포스트모템 액션에 '회귀 테스트 추가'를 포함시켜 같은 사고가 반복되지 않게 합니다. 좋은 테스트는 비용이 아니라, 두려움 없이 빠르게 변경하게 하는 속도의 기반입니다.

다음 모듈에서는 시간이 지나며 쌓이는 '기술 부채'와 리팩터링을, PM이 이해해야 할 비용 관점에서 다룹니다.

지식 확인

퀴즈 — 4문제

Q1

테스트 피라미드가 권장하는 비율은?

Q2

테스트 커버리지 80%가 의미하는 것과 그 함정은?

Q3

스모크 테스트(smoke test)의 목적은?

Q4

회귀 테스트(regression test)가 막으려는 것은?

0 / 4 답변

이것도 배워보세요