사전 큰 테스트
개념

큰 테스트

gabury1고친 사람 github-actions[bot]

큰 테스트는 테스트를 여러 머신에 걸쳐 돌려서 시스템 전체가 함께 도는지 확인합니다. 진짜 서버들을 진짜 네트워크로 이어 놓고 돌립니다. 그만큼 느리고 결과가 흔들리기 쉬워서 작은 테스트나 중간 테스트보다 적게 둡니다.

쉽고 빠른 이해

무슨 일을 하나 — 서로 다른 머신에 뜬 서버들을 이어 놓고 끝까지 도는지 봅니다. 주문 서버가 다른 머신의 결제 서버를 불러 결제까지 마치는지 확인하는 식입니다.

왜 이렇게 하나 — 상대 서버를 가짜로 바꿔 끼운 테스트는 쓴 사람이 짐작한 대로만 움직입니다. 서버 주소나 권한 같은 값이 머신 사이에서 어긋났는지는 진짜로 이어 봐야 압니다.

어떻게 도나

  1. 확인할 서버들을 여러 머신에 띄웁니다
  2. 테스트가 네트워크로 요청을 보냅니다
  3. 돌아온 결과가 기대와 같은지 봅니다

대가 — 느립니다. 네트워크 사정에 따라 같은 테스트가 붙었다 떨어졌다 합니다. 그래서 적게 두고 개발하는 동안에는 자주 돌리지 않습니다.

상세

이 절은 테스트를 크기로 나누는 잣대부터 봅니다. 그다음 그 잣대가 나눈 세 칸 가운데 가장 큰 칸이 무엇을 허락하는지 봅니다. 주문 서버와 결제 서버 두 대를 가지고, 큰 테스트가 무엇을 얻고 무엇을 치르는지 보입니다.

자동차 부품을 검사한다고 해 봅시다. 엔진 하나를 작업대에 올려 돌려 보면 금방 끝납니다. 결과도 늘 같습니다. 차를 다 조립해 도로에서 몰아 보면 한 번에 오래 걸립니다. 결과도 날씨와 교통에 따라 달라집니다. 그래도 부품끼리 맞물려 굴러가는지는 도로에서야 압니다.

테스트 크기라는 잣대

테스트 크기는 테스트가 어디서 도느냐로 테스트를 나눕니다. 코드 줄 수와는 상관이 없습니다. 이 잣대를 따로 두는 까닭은 테스트가 얼마나 빨리 끝나는지, 돌릴 때마다 같은 결과를 내는지가 도는 곳에 달려 있기 때문입니다.

도는 곳은 세 칸으로 나눕니다. 프로세스 하나 안, 머신 한 대 안, 여러 머신입니다. 프로세스는 실행 중인 프로그램 하나입니다. 아래 표는 칸마다 도는 곳과 허락되는 것을 모았습니다.

크기 도는 곳 허락되는 것
작은 테스트 프로세스 하나 안 프로세스 안의 계산과 메모리만
중간 테스트 머신 한 대 안 프로세스 여럿 · localhost 로 가는 네트워크 호출
큰 테스트 여러 머신에 걸쳐도 됨 다른 머신으로 가는 네트워크 호출

작은 테스트에는 디스크 읽기도, 네트워크 호출도 허락되지 않습니다. 코드를 정해진 시간 동안 멈춰 두고 기다리는 일(sleep)도 안 됩니다. 셋 다 테스트를 느리게 하거나 결과를 흔들 수 있기 때문입니다.

중간 테스트는 네트워크 호출을 하되 localhost 로만 보냅니다. localhost 는 자기 머신을 가리키는 이름입니다. 그래서 localhost 로 보낸 요청은 머신 밖으로 나가지 않습니다.

큰 테스트는 중간 테스트에 걸린 마지막 제한을 풉니다. 중간 테스트는 자기 머신 바깥으로 요청을 못 보냅니다. 큰 테스트는 테스트와 확인할 시스템이 여러 머신에 흩어져도 됩니다. 멀리 떨어진 클러스터의 시스템을 상대로 돌아도 됩니다. 클러스터는 한데 묶어 굴리는 머신 무리입니다.

주소 하나로 갈리는 크기

크기가 갈리는 지점은 테스트 코드에서 요청을 보내는 주소에 드러납니다. 아래 두 줄은 같은 주문 API(Application Programming Interface, 프로그램끼리 서로 부르는 창구)를 부릅니다. 다른 것은 주소뿐입니다.

Java
// 중간 테스트: 같은 머신의 서버
var url = "http://localhost:8080/orders";

// 큰 테스트: 다른 머신의 서버
var url = "http://10.0.3.7:8080/orders";

첫 줄은 테스트가 도는 머신에 띄운 주문 서버를 부릅니다. 둘째 줄의 10.0.3.7 은 다른 머신의 IP 주소입니다. IP(Internet Protocol) 주소는 네트워크에서 머신 한 대를 가리키는 번호입니다. 요청이 머신 밖으로 나가 네트워크를 지나므로 이 테스트는 큰 테스트가 됩니다.

주문 하나가 지나는 머신 세 대

테스트는 주문 서버에 주문을 보냅니다. 주문 서버는 다른 머신의 결제 서버를 부릅니다. 결제 서버는 또 다른 머신의 데이터베이스에 결제를 적습니다.

flowchart TD
    T["테스트"]
    subgraph A["머신 A"]
        O["주문 서버"]
    end
    subgraph B["머신 B"]
        P["결제 서버"]
    end
    subgraph C["머신 C"]
        D["데이터베이스"]
    end
    T -->|"주문 요청"| O
    O -->|"결제 요청"| P
    P -->|"결제 기록"| D

화살표 세 개가 전부 머신 경계를 넘습니다. 어느 하나라도 주소가 틀렸거나 막혀 있으면 이 테스트가 깨집니다. 작은 테스트와 중간 테스트로는 이 화살표들을 확인할 방법이 없습니다.

느리고 흔들리는 까닭

머신 경계를 넘는 요청은 머신 안에서 오가는 요청보다 오래 걸립니다. 요청 하나가 몇 배 느려지면, 그런 요청이 수십 번 오가는 테스트는 그만큼 길어집니다.

흔들림은 더 성가십니다. 결정성은 같은 입력에 늘 같은 결과를 내는 성질입니다. 결과가 흔들린다는 말은 이 성질을 잃었다는 뜻입니다. 큰 테스트는 네트워크와 다른 머신에 기대므로 이 성질을 잃기 쉽습니다.

네트워크가 잠깐 막히거나 다른 머신이 바쁘면 코드를 하나도 안 바꿨는데 테스트가 깨집니다. 이렇게 붙었다 떨어졌다 하는 테스트를 불안정한 테스트라고 부릅니다.

불안정한 테스트가 많아지면 깨져도 아무도 안 믿습니다. 그러다 진짜 잘못이 생겨 깨진 테스트까지 함께 흘려보내게 됩니다.

큰 테스트를 쓰는 경우

같은 것을 확인할 수 있으면 언제나 더 작은 테스트를 고르기를 권합니다. 큰 테스트는 다른 크기로는 확인할 수 없을 때만 씁니다. 그런 경우는 주로 둘입니다.

첫째는 시스템 전체를 처음부터 끝까지 지나는 테스트입니다. 이런 테스트가 주로 잡는 것은 코드의 잘못보다 설정의 잘못입니다. 설정은 서버 주소 · 포트 · 접근 권한처럼 코드 밖에서 넣어 주는 값입니다. 코드가 맞아도 설정이 틀리면 서버끼리 못 만납니다.

둘째는 오래된 부품이라 가짜로 바꿔 끼울 수 없는 경우입니다. 테스트 더블은 테스트에서 진짜 대신 쓰는 가짜입니다. 부품이 너무 얽혀 있어 가짜를 만들 수 없으면 진짜를 띄워서 확인할 수밖에 없습니다.

돌리는 때

큰 테스트는 작은 테스트나 중간 테스트와 따로 떼어 두는 일이 많습니다. 코드를 고칠 때마다 큰 테스트를 기다리면 개발이 멈추기 때문입니다.

그래서 큰 테스트는 대개 코드를 사용자에게 내보내기 직전에만 돌립니다. 이렇게 내보내는 일을 릴리스라고 합니다. 개발자가 코드를 고치는 동안에는 작은 테스트와 중간 테스트가 돕니다. 큰 테스트는 릴리스 직전에 한 번 더 확인합니다.

넓은 범위 테스트와 다른 축

큰 테스트와 넓은 범위 테스트는 이름이 닮았지만 서로 다른 잣대의 말입니다. 테스트 범위는 테스트가 무엇을 확인하느냐를 봅니다. 크기는 테스트가 어디서 도느냐를 봅니다.

두 잣대는 대개 함께 움직입니다. 시스템 전체를 확인하는 테스트는 여러 머신에 걸치기 쉽습니다. 그래도 늘 같이 가지는 않습니다.

결제 서버를 부르는 클래스 하나만 확인한다고 해 봅시다. 그 상대를 다른 머신의 진짜 결제 서버로 두면 범위는 좁고 크기는 큽니다. 반대로 시스템 전체를 머신 한 대에 몰아 띄워 처음부터 끝까지 확인하면 범위는 넓고 크기는 중간입니다.

관련 항목

큰 테스트와 같은 크기 잣대로 나뉘는 테스트

테스트 크기 · 작은 테스트 · 중간 테스트 · 허미틱 테스트

큰 테스트와 다른 축인 범위로 나뉘는 테스트

테스트 범위 · 좁은 범위 테스트 · 중간 범위 테스트 · 넓은 범위 테스트 · 종단 간 테스트 · 시스템 테스트 · 통합 테스트 · 단위 테스트

큰 테스트가 잃기 쉬운 성질과 그 증상

결정성 · 불안정한 테스트 · 지연 · 테스트 격리

큰 테스트를 돌리는 단계와 환경

빌드 · 릴리스 엔지니어링 · 지속적 통합 · 스테이징 환경 · 클러스터

큰 테스트 대신 쓸 수 있는 수단

테스트 더블 · 페이크 객체 · 계약 테스트

큰 테스트의 개수를 정하는 배분 모양

테스트 피라미드 · 테스팅 트로피 · 아이스크림 콘 안티패턴

다른 이름: large test · large tests · 대형 테스트