LabHub

블로그

테스트의 현대 — 단위·통합·E2E·Playwright·Property-based·Mutation·Fuzz·Chaos·AI 생성 테스트 심층 가이드 (2025)

2025년의 테스트는 왜 다시 뜨거운가

2010년대는 "유닛 테스트 다다익선" 시대였다. 커버리지 숫자가 팀 자랑이었고, @Test 어노테이션 아래 assertEquals(1+1, 2)가 쌓였다. 2020년대 초에 그 반성이 왔다 — "우리는 많이 썼는데 왜 프로덕션에서 터지나". 단위 테스트가 mock으로 가득해 실제 통합 문제를 잡지 못했다는 진단. Kent C. Dodds가 Testing Trophy를 제안했고(2018~), 업계는 통합 테스트 중심으로 무게추를 옮겼다. 거기에 Playwright의 압도적 완성도가 Cypress를 밀어내고 E2E의 표준으로 올라섰다.

동시에 테스트의 자동 생성이 현실이 되었다. Qodo(Codium)·Diffblue Cover·CodiumAI가 기존 코드에 테스트를 만들어준다. 성능·보안 영역에서는 Property-based TestingFuzz Testing이 주류화했고, LLM 시스템 자체를 평가하는 Eval이 새로운 테스트 카테고리로 떴다. 인프라 회복력은 Chaos Engineering이 Netflix 이후 성숙했다.

이 글은 그 2025년 테스트 판의 지형을 해부한다.

이 글은 앞선 엔지니어링 글쓰기코드 리뷰 가이드의 자매편이다. 좋은 글 + 좋은 리뷰 + 좋은 테스트가 품질 문화의 삼각형이다.

1부. Testing Pyramid·Trophy·Diamond — 형태 전쟁

1.1 기존 피라미드 (Mike Cohn, 2009)

문제: "유닛이면 빠르니까" 철학에서 mock이 남발되어 실제 계약 위반을 못 잡음.

1.2 Testing Trophy (Kent C. Dodds, 2018)

프런트엔드에서 특히 설득력을 얻었고, React Testing Library 철학과 결합.

1.3 Testing Diamond (Google 등)

백엔드 마이크로서비스 세계에서 수렴한 형태.

1.4 어떤 모양이든 공통 원칙

2부. 유닛 테스트 — 진짜 필요한 것과 잉여

2.1 언제 유닛 테스트가 빛나는가

2.2 유닛 테스트가 잉여가 되는 순간

2.3 테스트 이중화 전략 (Test Double)

2025년 합의: Fake를 선호, mock은 인터페이스 경계에서만.

2.4 도구

3부. 통합 테스트 — Testcontainers 혁명

3.1 전통적 고통

3.2 Testcontainers — 2020 이후 대세

import { PostgreSqlContainer } from "@testcontainers/postgresql";

const db = await new PostgreSqlContainer("postgres:16").start();
const conn = await connect(db.getConnectionUri());
// 실제 Postgres에서 통합 테스트
await db.stop();

3.3 Ephemeral Environment — PR마다 서비스 전체

3.4 Service Virtualization

3.5 Snapshot 테스트의 함정

4부. E2E — Playwright의 독주

4.1 Cypress의 흥망

4.2 Playwright (Microsoft, 2020~)

4.3 Cypress가 여전히 살아남는 영역

4.4 WebdriverIO·TestCafe·Nightwatch

4.5 E2E 안티패턴

5부. Visual Regression — 픽셀 수준 회귀

5.1 왜 필요한가

5.2 도구

5.3 AI 기반 비교

6부. Contract Testing — 마이크로서비스 간 안전망

6.1 문제

6.2 Consumer-Driven Contract

6.3 Pact Broker

6.4 Schema-first 접근

6.5 실전 도입

7부. Property-based Testing — 수학이 버그를 찾는다

7.1 개념

7.2 전설 — Jepsen

7.3 언어별 주력

7.4 예제

from hypothesis import given, strategies as st

@given(st.lists(st.integers()))
def test_reverse_twice_is_identity(xs):
    assert list(reversed(list(reversed(xs)))) == xs

"리스트를 뒤집어 두 번 뒤집으면 원래". 1000개 랜덤 리스트가 자동 생성돼 검증.

7.5 실전 팁

8부. Mutation Testing — 테스트의 테스트

8.1 개념

8.2 도구

8.3 왜 적게 쓰나

8.4 진지하게 쓰는 곳

9부. Fuzz Testing — 랜덤이 발견하는 취약점

9.1 개념

9.2 도구

9.3 OSS-Fuzz

Google이 오픈소스 라이브러리를 상시 fuzzing. 수천 CVE 발굴. 참여하면 무료로 CI급 자원 제공.

9.4 Coverage-guided Fuzzing

9.5 Differential Fuzzing

10부. Chaos Engineering — 실패를 연습하는 기술

10.1 Netflix가 시작한 패러다임

10.2 실험 설계

10.3 도구

10.4 Chaos가 성숙하는 조건

11부. AI 생성 테스트 — 2024~2025 폭발

11.1 도구

11.2 현실

11.3 생산성 영향

11.4 LLM Eval — 새 카테고리

12부. Flaky Test — 10년된 숙제

12.1 원인 분류

12.2 탐지

12.3 해결 패턴

12.4 문화

13부. 성능·부하 테스트

13.1 도구

13.2 시나리오

13.3 CI 통합

14부. 실전 — 팀 규모별 테스트 전략

14.1 5명

14.2 50명

14.3 500명+

15부. 체크리스트 12 · 안티패턴 10

✅ 체크리스트 12

  1. Testing Trophy/Diamond 중 하나의 모양을 팀이 의식하는가?
  2. Testcontainers로 실제 DB를 쓰는 통합 테스트가 있는가?
  3. Playwright로 핵심 happy path E2E가 있는가?
  4. Pact 또는 Schema 기반 contract test가 있는가?
  5. Property-based test가 핵심 알고리즘에 1~5개 있는가?
  6. Mutation testing이 분기마다 또는 주기적으로 돌아가는가?
  7. Visual regression이 디자인 시스템에 붙어 있는가?
  8. Flaky test가 3% 임계로 자동 격리되는가?
  9. Fuzz testing이 파서/프로토콜 코드에 있는가?
  10. Chaos experiment가 분기 1회 이상 실행되는가?
  11. CI가 10분 이하에 끝나는가?
  12. LLM 사용 기능에 eval suite가 있는가?

⚠️ 안티패턴 10

  1. 커버리지 숫자만 쫓다가 mock이 mock을 부름
  2. Snapshot을 의미 없이 업데이트 ("그냥 바뀌었네")
  3. Flaky를 retry 3 으로 덮음
  4. E2E 1,000개를 매 PR마다 돌림
  5. Contract test 없이 마이크로서비스 30개
  6. prod DB에 직접 접속하는 통합 테스트
  7. AI가 만든 테스트를 검증 없이 머지
  8. Chaos 실험을 prod에서 관측가능성 없이
  9. 성능 테스트를 릴리스 전날에만
  10. LLM 응답 회귀를 수동 확인 (eval 없음)

다음 글 예고 — "프로덕트 엔지니어링: 사양·실험·A/B·Feature Flag·RICE·OKR·엔지니어-PM 협업·고객 인터뷰" — 기술이 아니라 가치를 만드는 엔지니어

테스트까지 왔다면, 이제 '무엇을 만들 것인가'라는 가장 상위 질문이다. 다음 글은 기술이 아니라 제품을 만드는 엔지니어의 일.

기술이 아닌 가치가 엔지니어의 마지막 렌즈다. 다음 편에서 그 렌즈를 닦는다.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다