테스트의 형태 — 피라미드·아이스크림콘·트로피·허니콤

「어떤 종류의 테스트를, 얼마나 써야 하는가」라는 물음에 소프트웨어 업계는 2000년대 중반 이후 여러 도상을 만들어냈다. Mike Cohn의 테스트 피라미드, Alister Scott의 아이스크림콘, Kent C. Dodds의 테스팅 트로피, Spotify의 테스팅 허니콤까지, 각 모델의 제창자와 주장의 차이를 따라가며 이 논쟁이 왜 지금도 끝나지 않았는지 정리한다.

testinghistorytest-pyramidtesting-trophytest-strategy

「어떤 종류의 테스트를, 얼마나 써야 하는가」라는 물음에 대해 소프트웨어 업계는 2000년대 중반 이후 여러 도상——피라미드, 아이스크림콘, 트로피, 허니콤——을 만들어냈다. 이는 단순한 비유가 아니라, 각 시대의 개발 체제·아키텍처·테스트 도구의 제약을 반영한, 「그 시점에서 가장 비용 대비 효과가 높은 테스트 배분」에 대한 주장이다. 이 글에서는 이 논의가 어떻게 시작되어 어떻게 갈라졌는지, 그리고 왜 지금도 결론이 나지 않았는지를 각 모델의 제창자와 주장의 차이를 따라 정리한다.

테스트 전략이 문제가 되는 것은 테스트를 무한히 쓸 수는 없기 때문이다. 같은 동작을 검증하는 테스트라도, 단위가 세밀할수록 빠르고 안정적이며 원인 특정이 쉬워지고, 단위가 굵을수록 「사용자에게 있어서의 가치」에 가까워지는 대신 느리고 잘 깨진다. 이 이율배반을 어떻게 배분할 것인가라는 물음에 각 모델은 저마다 다른 답을 내놓았다.

테스트 피라미드의 기원 — Mike Cohn

테스트 피라미드라는 개념의 기원은 애자일 코치 Mike Cohn으로 거슬러 올라간다. Cohn은 Lisa Crispin과의 대화 속에서 2003~2004년 무렵 이 그림을 그렸고, 2009년 저서 『Succeeding with Agile: Software Development Using Scrum』에서 「테스트 자동화 피라미드(Test Automation Pyramid)」로 문서화했다. Cohn의 원래 3계층 모델은 다음과 같다.

  1. Unit Tests(최하층·최다) — 개별 함수·클래스를 검증. 빠르다
  2. Service Tests(중간층) — API나 서비스 경계를 검증
  3. UI Tests(최상층·최소) — GUI를 통한 엔드투엔드 검증. 느리고 잘 깨진다

Cohn 주장의 핵심은 「UI를 경유하는 테스트는 자동화 비용이 높고 잘 깨지므로, 가능한 한 얇은 층에 머물게 하고 로직의 대부분은 아래층에서 검증하라」는 배분의 지침이며, 단순한 분류가 아니라 자원 배분 전략으로 제시되었다는 점이 중요하다.

Martin Fowler에 의한 보급과 정식화

Cohn의 모델은 원래 애자일 커뮤니티 내부의 논의였지만, Martin Fowler가 2012년 자신의 bliki에 “TestPyramid”라는 짧은 글을 쓰면서 업계 전체에 널리 알려지게 되었다. Fowler는 「유닛 테스트를 많이, 통합 테스트를 적당히, E2E 테스트를 적게」라는 일반화된 형태로 피라미드를 재정식화했고, 아울러 「아이스크림콘」이라는 역전 패턴에 대해서도 언급하며 경종을 울렸다.

나아가 2018년에는 Fowler의 사이트에 Ham Vocke(Thoughtworks)가 쓴 “The Practical Test Pyramid”라는 장문의 글이 게재되어, 추상적인 비유였던 피라미드를 실제 코드 예시를 동반한 실천적 가이드로 살을 붙였다. 이 글은 「피라미드는 개념으로서는 옳지만, 현장에서 어떻게 구현할지에 대한 해상도가 부족하다」는 불만에 답하는 형태로 쓰였다.

아이스크림콘 — 역피라미드라는 반면교사

피라미드와 짝을 이루는 반면교사로 널리 인용되는 것이 「아이스크림콘(Ice-Cream Cone)」이다. Watir 커뮤니티의 핵심 기여자였던 Alister Scott이 2012년 블로그 글 “Testing Pyramids & Ice-Cream Cones”에서 이 명칭을 제시했다. 실제 조직에서 흔히 볼 수 있는 다음과 같은 역전된 배분을 가리킨다.

  • 수동 테스트가 가장 많은 양을 차지한다
  • UI 자동화 테스트가 그 뒤를 잇는다
  • 통합 테스트는 중간 정도다
  • 유닛 테스트가 가장 적다

이 형태가 되면 테스트 스위트 실행에 시간이 걸리고, 실패 원인 특정이 어려워지며, 플레이키(flaky, 불안정)한 테스트에 대한 불신 때문에 테스트가 형식화되는 악순환에 빠진다. 아이스크림콘은 「의도적으로 선택한 전략」이 아니라 테스트를 사후에 덧붙여 쌓아 올린 결과로 자연 발생하는 경우가 많으며, 그런 점에서 피라미드와의 대비는 「설계된 것인가, 방치의 산물인가」라는 차이이기도 하다.

테스팅 트로피의 등장 — Kent C. Dodds

2017년 전후, 자바스크립트 커뮤니티에서 React 등 컴포넌트 지향 프런트엔드가 주류가 되는 가운데, Kent C. Dodds는 “Write tests. Not too many. Mostly integration.“이라는 발표·블로그 글, 그리고 뒤이은 “The Testing Trophy and Testing Classifications”에서 「테스팅 트로피(Testing Trophy)」를 제창했다. 이전 기사에서 본 Testing Library 역시 같은 Dodds의 설계다.

트로피는 아래에서부터 다음 4개 층으로 구성된다.

  1. 정적 분석(Static) — 타입 체크·린트. 토대
  2. 유닛(Unit)
  3. 통합(Integration) — 트로피 중 가장 넓은 층 = 가장 투자해야 할 층
  4. E2E — 정점, 소수

Dodds의 주장은 「2012년 당시와 달리, 현대적인 테스트 도구(Jest, React Testing Library, 이후의 Playwright 등)에 의해 더 넓은 범위를 검증하는 테스트가 예전만큼 느리고, 비싸고, 잘 깨지지 않게 되었다」는 전제의 변화에 근거한다. 표어 “The more your tests resemble the way your software is used, the more confidence they can give you.”(테스트가 소프트웨어의 실제 사용 방식에 가까울수록, 그 테스트는 더 높은 확신을 준다)는 구현 세부사항이 아니라 사용자에게 보이는 동작을 검증해야 한다는 가치관을 단적으로 나타낸다. 피라미드의 부정이라기보다는, 「어느 층에 가장 투자해야 하는가」의 무게중심을 유닛에서 통합으로 옮기는 재조정이다.

허니콤 모델 — 마이크로서비스의 관점

프런트엔드와는 별개의 맥락에서, Spotify의 엔지니어링 팀은 2018년 블로그 글 “Testing of Microservices”에서 「테스팅 허니콤(Testing Honeycomb)」을 제시했다. 마이크로서비스 아키텍처에서는 서비스 단독 로직의 복잡함보다 「서비스 간 연결 지점」의 복잡함이 더 지배적이 된다는 관찰에 근거해, 피라미드의 중간층(통합 테스트)을 가장 큰 층으로 부풀리고 유닛과 UI(E2E) 양쪽 끝을 상대적으로 얇게 하는 형태를 제안했다. 이는 트로피와 발상은 가깝지만, 프런트엔드의 「컴포넌트의 통합」이 아니라 「서비스 간 API의 통합」에 초점이 맞춰져 있다는 점이 다르다.

형태 논쟁의 배경에 있는 구조 변화

왜 2012년의 피라미드가 2017~2018년에 잇따라 이의 제기를 받았을까. 배경에는 다음과 같은 환경 변화가 있다.

  • 마이크로서비스화 — 모놀리스에서는 「유닛」으로 지킬 수 있었던 로직이, 서비스 분할 후에는 「서비스 간 연계」로 이동해 통합층의 상대적 중요성이 커졌다
  • 프런트엔드의 컴포넌트화 — React/Vue 이후, UI는 「개별 함수」보다 「렌더링된 동작」 단위로 테스트하는 편이 가치가 높아졌다
  • 테스트 도구의 고속화·안정화 — Cypress(2015년 공개), 이후의 Playwright(2020년 공개) 등에 의해 브라우저 테스트의 실행 속도와 결정성이 2012년 당시보다 크게 개선되었다
  • CI 환경의 병렬화 — 클라우드 CI에 의해, 예전에는 「너무 느려서 피해야 할」 테스트의 병렬 실행 비용이 낮아졌다

즉 각 모델은 보편적인 물리 법칙이 아니라, 「그 시대의 제약 아래에서 무엇에 투자하는 것이 가장 수지가 맞는가」라는 경제적 합리성의 주장이다. 도구가 바뀌면 최적의 배분도 바뀔 수 있다는 전제를 공유한 위에서의 의견 차이라고 이해하는 것이 정확하다.

구글의 「테스트 사이즈」라는 대안적 분류축

피라미드 계열의 모델이 모두 「유닛/통합/E2E」라는 테스트의 대상 범위(scope) 로 층을 나누는 데 비해, 구글은 저서 『Software Engineering at Google』(Titus Winters, Tom Manshreck, Hyrum Wright 편, O’Reilly, 2020년)에서 범위가 아니라 실행 시 허용되는 자원 제약으로 테스트를 분류하는 「테스트 사이즈(test size)」라는 축을 제시한다.

사이즈 실행 환경의 제약 전형적인 특징
Small 단일 프로세스 안에서 완결. 네트워크·디스크·별도 프로세스 접근 불가 빠르고 결정적. 대체로 유닛 테스트에 해당
Medium 단일 머신 안에서 완결. localhost 통신이나 디스크 접근은 허용 DB·로컬 서비스를 쓰는 통합 테스트에 해당하는 경우가 많음
Large 여러 머신·외부 네트워크 접근도 허용 E2E에 가깝지만 「범위」가 아니라 「제약의 느슨함」으로 정의됨

이 분류의 이점은, 「이것은 유닛 테스트인가 통합 테스트인가」라는 소모적인 논쟁을 피하고, CI 위에서 「이 테스트는 네트워크에 접근해도 되는가」 「병렬 실행 시 다른 테스트와 자원을 다투지 않는가」라는 운용상의 제약으로 기계적으로 검사할 수 있다는 점에 있다. 범위에 의한 분류와 자원 제약에 의한 분류는 배타적이지 않으며, 같은 테스트 스위트에 대한 두 가지 다른 관점으로 병용되는 경우가 많다.

비용·속도·신뢰성·결정성의 트레이드오프

관점 유닛 통합/계약 E2E
실행 속도 매우 빠름(ms) 중간 속도(초) 느림(초~분)
결정성(같은 결과를 반환하는가) 높음 중간 정도(외부 의존에 따라 다름) 낮아지기 쉬움(환경·타이밍 의존)
작성 비용 낮음 중간 정도 높음(셀렉터·대기·데이터 준비)
유지보수 비용 낮음(구현 비의존적으로 작성하면) 중간 정도 높음(UI 변경에 잘 깨짐)
얻어지는 확신도 로직 단위 연계 부분 사용자 가치의 사슬 전체
실패 원인 특정 용이성 쉬움 비교적 쉬움 어려움(어디서 깨졌는지 탐색 필요)

이 표가 보여주듯, 단일 지표로는 「어느 층이 우수한가」가 정해지지 않는다. 전략이란 이 여러 지표 중 무엇을 우선할 것인가라는 가치 판단 그 자체다.

모델 비교표

모델 제창자·출처 상정 문맥 무게중심
테스트 피라미드 Mike Cohn(2009년 저서, 2003~2004년 무렵 착안) / Martin Fowler(2012년 bliki) 애자일 개발 전반 유닛을 최대량, UI를 최소한으로
아이스크림콘 Alister Scott(2012년) 사후에 테스트를 쌓아 올린 현장 피해야 할 안티패턴으로 제시
테스팅 트로피 Kent C. Dodds(2017년 전후) 현대 JS/프런트엔드 통합 테스트에 대한 중점 투자
테스팅 허니콤 Spotify 엔지니어링 블로그(2018년) 마이크로서비스 서비스 간 연계 검증을 최대화

논쟁에서 배우는 것

각 모델의 대립에서 얻을 수 있는 실무적 교훈은 「유일한 정답이 되는 형태는 없다」는 점으로 귀결된다. 전략을 세울 때 물어야 할 질문은 다음과 같은 것들이다.

  • 우리의 아키텍처에서 복잡함이 집중되어 있는 곳은 어디인가(로직 내부인가, 연계 지점인가, UI인가)
  • 지금 손에 있는 테스트 도구는 어느 층의 실행을 빠르고 안정적으로 할 수 있는 상태인가
  • 팀이 테스트 실패를 신뢰하고 있는가(플레이키 테스트의 축적은 층에 관계없이 전략을 파탄시킨다)
  • 변경 빈도가 높고 위험이 큰 기능은 어디인가(그곳에 투자를 두텁게 한다)

피라미드를 문자 그대로 「UI 테스트를 줄이면 된다」고만 받아들이지 말고, 「왜 그 형태가 제안되었는가」라는 배경의 경제적 합리성을 이해해, 자신들의 아키텍처에 맞춰 형태를 다시 선택하는 것이야말로 이 논쟁에서 끌어낼 수 있는 가장 큰 실무적 가치다.

이 기사에서 다음 기사로

테스트의 「배분」을 둘러싼 논쟁을 따라왔다. 다음 기사에서는 시점을 개별 테스트의 내용으로 옮겨, 유닛 테스트의 설계와 계약(contract)이라는, 테스트의 「단위」보다 한층 더 안쪽에 있는 설계 원칙을 살펴본다.

← Back to 소프트웨어 테스트의 계보