테스트 피라미드
고친 사람 github-actions[bot]
테스트 피라미드는 자동화 테스트 가운데 어느 종류를 더 많이 둘지 정해 줍니다. 좁은 범위를 빠르게 보는 테스트를 가장 많이 둡니다. 시스템 전체를 느리게 도는 테스트는 가장 적게 둡니다. 개수를 계층으로 쌓으면 아래가 넓은 삼각형이 되어 이런 이름이 붙었습니다.
쉽고 빠른 이해
무슨 일을 하나 — 넓이가 다른 테스트 가운데 어느 쪽을 더 많이 짤지 정합니다. 주문 서버라면 할인 계산 함수 하나를 보는 테스트는 많이, 화면에서 주문 버튼까지 누르는 테스트는 몇 개만 둡니다.
왜 하나 — 시스템 전체를 도는 테스트는 느리고 자주 흔들립니다. 실패해도 어디가 틀렸는지 바로 안 보입니다. 이런 테스트만 잔뜩 두면 한 번 돌리는 데 한참 걸립니다. 결과를 믿기도 어렵습니다.
어떻게 도나
- 함수 하나하나는 금방 끝나는 테스트로 촘촘히 확인합니다
- 부품이 붙는 이음매는 그보다 적은 테스트로 확인합니다
- 사용자 흐름 전체는 꼭 필요한 몇 개로만 확인합니다
대가 — 아래 계층 테스트는 진짜 부품 대신 가짜를 많이 씁니다. 가짜가 진짜와 다르게 굴면 아래 계층이 다 통과해도 운영에서 깨집니다. 그래서 위 계층을 없애지 않고 좁히기만 합니다. 요청을 거의 그대로 데이터베이스에 쓰는 서버는 가운데 계층을 가장 두껍게 두기도 합니다.
상세
주문을 받는 백엔드 서버 하나를 예로 삼아 끝까지 따라갑니다.
테스트를 넓이로 나누는 세 계층
자동화 테스트는 사람이 손으로 눌러 보는 대신 코드로 짜 두고 기계가 돌리는 테스트입니다. 한 번 짜 두면 코드를 고칠 때마다 몇 번이고 다시 돌릴 수 있습니다. 테스트 피라미드는 이 자동화 테스트를 한 번에 얼마나 넓게 보느냐로 나눕니다.
가장 좁은 계층은 단위 테스트입니다. 함수나 클래스 하나를 떼어 확인합니다. 주문 서버라면 할인 금액을 계산하는 함수 하나에 값을 넣고 결과를 봅니다. 데이터베이스나 네트워크를 부르지 않아서 금방 끝납니다.
가운데 계층은 통합 테스트입니다. 부품 여럿을 붙이거나, 코드와 데이터베이스 같은 바깥 시스템을 붙여서 확인합니다. 주문을 저장하는 코드가 진짜 데이터베이스에 행을 제대로 쓰는지 보는 테스트가 여기 듭니다. 부품끼리 만나는 이음매를 확인하는 계층입니다.
가장 넓은 계층은 종단 간 테스트입니다. 사용자가 쓰는 흐름을 처음부터 끝까지 따라갑니다. 브라우저를 띄워 상품을 담고 주문 버튼을 누른 뒤 주문 완료 화면이 뜨는지 봅니다. 서버와 데이터베이스와 결제 연동이 전부 떠 있어야 돌릴 수 있습니다.
계층 이름은 사람마다 조금씩 다르게 부릅니다. 가운데 계층을 서비스 테스트, 꼭대기를 UI(User Interface, 사용자 인터페이스) 테스트라고 부르기도 합니다. 이 편은 단위·통합·종단 간으로 통일합니다.
넓은 테스트가 비싼 까닭
계층이 올라갈수록 테스트 하나가 치르는 값이 커집니다. 그 값은 셋입니다. 시간과 흔들림과 실패가 가리키는 범위입니다.
첫째는 시간입니다. 종단 간 테스트는 서버를 띄우고 데이터베이스를 채우고 브라우저를 움직여야 합니다. 단위 테스트가 눈 깜짝할 새 끝나는 동안 종단 간 테스트는 그보다 훨씬 오래 걸립니다. 테스트가 느리면 개발자는 코드를 고칠 때마다 돌려 보지 않게 됩니다.
둘째는 흔들림입니다. 붙은 부품이 많을수록 코드와 상관없는 이유로 실패할 틈이 늘어납니다. 네트워크가 잠깐 느려지거나 화면이 늦게 그려지면 코드가 멀쩡해도 실패합니다. 코드를 안 고쳐도 돌릴 때마다 결과가 바뀌는 테스트가 불안정한 테스트입니다.
셋째는 실패가 가리키는 범위입니다. 할인 계산 단위 테스트가 실패하면 틀린 곳은 그 함수 하나입니다. 주문 흐름 종단 간 테스트가 실패하면 화면, 서버, 데이터베이스, 결제 연동 어디든 원인일 수 있습니다. 원인을 찾는 데 시간이 또 듭니다.
세 계층을 이 세 값으로 한 표에 모으면 이렇습니다.
| 계층 | 확인하는 범위 | 도는 시간 | 흔들림 | 실패했을 때 |
|---|---|---|---|---|
| 단위 테스트 | 함수나 클래스 하나 | 가장 짧다 | 거의 없다 | 틀린 함수가 바로 나온다 |
| 통합 테스트 | 부품끼리 만나는 이음매 | 중간 | 가끔 있다 | 어느 이음매인지 찾아야 한다 |
| 종단 간 테스트 | 사용자 흐름 전체 | 가장 길다 | 잦다 | 원인이 어디든 있을 수 있다 |
위로 갈수록 시간과 흔들림과 원인 찾기가 모두 나빠집니다. 대신 위 계층은 아래 계층이 못 보는 것을 봅니다. 부품을 다 붙였을 때만 드러나는 잘못이 그렇습니다.
아래가 넓은 모양
그래서 값이 싼 테스트를 많이, 비싼 테스트를 적게 둡니다. 단위 테스트를 가장 많이 둡니다. 통합 테스트는 그보다 적게 둡니다. 종단 간 테스트는 가장 적게 둡니다. 개수를 계층으로 쌓으면 아래가 넓고 위가 좁은 삼각형이 됩니다.
block-beta columns 5 space:2 e["종단 간"]:1 space:2 space i["통합"]:3 space u["단위"]:5
계층마다 몇 개를 둘지 정해진 수는 없습니다. 피라미드가 정하는 것은 계층 사이에 어느 쪽이 더 많아야 하는가입니다. 아래 계층이 위 계층보다 많으면 모양을 지킨 것입니다.
버그는 잡을 수 있는 가장 낮은 계층에서
한 가지 동작을 여러 계층에서 되풀이해 확인하지 않습니다. 할인 금액이 맞는지는 단위 테스트가 이미 봅니다. 종단 간 테스트까지 할인 금액을 하나하나 확인하면 오래 걸리는 테스트가 같은 일을 한 번 더 하는 셈입니다.
위 계층은 아래 계층이 못 보는 것만 봅니다. 통합 테스트는 부품이 서로 말을 제대로 주고받는지 봅니다. 종단 간 테스트는 사용자가 가장 자주 쓰는 흐름이 끝까지 이어지는지만 봅니다.
위 계층 테스트가 버그를 잡으면 아래 계층에 같은 버그를 잡는 테스트를 하나 보탭니다. 할인이 잘못 붙은 것을 종단 간 테스트가 찾았다면, 그 입력을 넣는 단위 테스트를 새로 씁니다. 다음에 같은 실수가 생기면 금방 끝나는 계층에서 먼저 걸립니다.
모양이 뒤집히는 경우
테스트를 위가 넓고 아래가 좁게 쌓은 팀도 흔합니다. 단위 테스트는 거의 없고 종단 간 테스트와 사람이 손으로 하는 확인이 대부분인 모양입니다. 콘 위에 아이스크림을 수북이 얹은 꼴이라 아이스크림 콘이라고 부릅니다.
이 모양은 대개 저절로 생깁니다. 화면을 눌러 보는 테스트는 코드 구조를 몰라도 짤 수 있어서 먼저 늘어납니다. 단위 테스트는 코드가 떼어 시험하기 좋게 짜여 있어야 쓸 수 있습니다.
뒤집힌 모양에서는 「넓은 테스트가 비싼 까닭」에서 본 세 가지 값이 전부 커집니다. 테스트를 한 번 다 돌리는 데 오래 걸립니다. 실패가 잦습니다. 실패해도 원인을 찾기 어렵습니다. 코드를 합칠 때마다 테스트를 자동으로 돌리는 지속적 통합에서는 이 시간이 곧 개발자가 기다리는 시간이 됩니다.
아래 계층을 넓힐 때 잃는 것
단위 테스트는 부품 하나를 떼어 내려고 진짜 의존 부품 대신 가짜를 끼웁니다. 이 가짜가 테스트 더블입니다. 가짜가 진짜와 다르게 굴면 단위 테스트가 다 통과해도 운영에서 깨집니다. 그래서 피라미드는 위 계층을 없애지 않고 좁히기만 합니다.
단위 테스트가 코드 속사정에 묶이기도 합니다. 함수를 어떻게 나눴는지까지 테스트가 알면, 동작은 두고 구조만 바꾸는 리팩터링에도 테스트가 깨집니다. 단위 테스트가 많을수록 같이 고칠 테스트도 많아집니다.
가운데 계층을 넓히는 모양
모든 서버에 이 모양이 맞지는 않습니다. 받은 요청을 거의 손대지 않고 데이터베이스에 쓰고 읽는 서버는 따로 떼어 시험할 계산이 적습니다. 이런 서버에서 버그는 대개 쿼리와 데이터베이스가 만나는 이음매에서 납니다.
그래서 통합 테스트를 가장 두껍게 두자는 모양도 있습니다. 이 모양의 이름은 테스팅 트로피입니다.
우승 트로피는 좁은 받침과 가는 기둥 위에 불룩한 잔이 얹힌 꼴입니다. 그 불룩한 잔이 통합 테스트입니다.
어느 모양이든 따르는 기준은 같습니다. 버그가 나는 곳을 가장 싸게 잡을 수 있는 계층에 테스트를 몰아 둡니다.
관련 항목
피라미드를 이루는 테스트 계층
단위 테스트 · 통합 테스트 · 종단 간 테스트 · 서비스 테스트 · UI 테스트 · 컴포넌트 테스트
피라미드와 맞세워지는 테스트 구성 모양
아이스크림 콘 안티패턴 · 테스팅 트로피 · 테스팅 벌집 · 테스트 다이아몬드
테스트를 나누는 다른 분류 기준
테스트 크기 · 테스트 범위 · 좁은 범위 테스트 · 넓은 범위 테스트 · 작은 테스트 · 큰 테스트
이 모양으로 짠 테스트를 돌리는 흐름
테스트 스위트 · 지속적 통합 · 회귀 테스트 · 스모크 테스트 · 테스트 샤딩 · 병렬 실행
위 계층 테스트를 비싸게 만드는 문제
불안정한 테스트 · 테스트 실행 시간 · 테스트 환경 · 테스트 데이터
아래 계층을 떼어 시험하게 해 주는 설계 기법
테스트 더블 · 목 객체 · 스텁 · 의존성 주입 · 리팩터링
테스트 피라미드가 놓이는 분야와 개발 방식
QA와 테스트 · 자동화 테스트 · 테스트 전략 · 테스트 주도 개발 · 애자일 소프트웨어 개발
다른 이름: test pyramid · Test Pyramid · test automation pyramid · 테스트 자동화 피라미드 · 테스팅 피라미드