사전 좁은 범위 테스트
개념

좁은 범위 테스트

gabury1고친 사람 github-actions[bot]

좁은 범위 테스트는 코드의 작은 부분 하나를 골라 그 논리가 맞는지 확인합니다. 테스트가 확인하는 코드의 양을 좁음·중간·넓음 세 칸으로 나누면 가장 좁은 칸입니다. 흔히 단위 테스트라고 부르는 것이 이것입니다. 확인하는 코드가 작아서 실패하면 틀린 곳이 바로 드러납니다.

쉽고 빠른 이해

무슨 일을 하나 — 클래스 하나나 메서드 하나만 골라 맞게 도는지 확인합니다. 「상품 값 3천 원과 4천 원을 넣으면 합계 7천 원이 나와야 한다」를 코드로 적어 두는 식입니다.

왜 이렇게 하나 — 넓게 확인하는 테스트는 깨졌을 때 원인이 어디든 있을 수 있습니다. 좁게 확인하면 깨진 테스트 이름만 보고도 고칠 곳을 압니다. 금방 끝나서 많이 두고 자주 돌릴 수 있습니다.

어떻게 도나

  1. 확인할 부분 하나를 정합니다
  2. 그 부분을 부르고 나온 값을 받습니다
  3. 기대한 값과 같은지 봅니다

대가 — 부분마다 맞아도 부분을 이은 곳에서 깨질 수 있습니다. 그래서 더 넓게 확인하는 테스트를 조금은 따로 둡니다.

상세

이 절은 테스트를 가르는 잣대 하나를 봅니다. 잣대의 이름은 범위입니다. 주문 금액의 합계를 내는 작은 클래스 하나를 가지고, 좁은 범위가 무엇을 확인하고 무엇을 확인하지 않는지 보입니다.

전기 기사가 콘센트 하나를 점검한다고 해 봅시다. 콘센트에 전기가 오려면 벽 속 전선과 차단기에도 전기가 흘러야 합니다. 그래도 점검표에 적는 것은 그 콘센트 하나가 제대로 되느냐입니다.

테스트 범위라는 잣대

테스트 범위는 테스트 하나가 맞는지 확인하는 코드의 양입니다. 확인하는 코드가 적을수록 범위가 좁습니다. 테스트를 부르는 이름이 팀마다 달라서, 이 잣대로 재면 같은 테스트를 같은 말로 부를 수 있습니다.

좁은 범위 테스트는 코드에서 작은 부분 하나의 논리를 확인합니다. 작은 부분은 보통 클래스 하나나 메서드 하나입니다. 흔히 단위 테스트라고 부르는 테스트가 이것입니다.

범위를 좁히는 까닭은 깨졌을 때 드러납니다. 확인한 코드가 메서드 하나면 테스트가 깨졌을 때 볼 곳도 그 메서드 하나입니다. 범위가 넓으면 화면부터 데이터베이스까지 어디든 원인일 수 있어서 찾는 데 시간이 듭니다.

범위는 세 칸으로 나눕니다. 아래 표는 칸마다 무엇을 확인하고 어떤 이름으로 부르는지 모았습니다.

범위 확인하는 것 부르는 이름
좁은 범위 클래스 하나나 메서드 하나의 논리 단위 테스트
중간 범위 테스트 부분 몇 개가 서로 주고받는 것(서버와 데이터베이스 사이 등) 통합 테스트
넓은 범위 테스트 시스템의 여러 부분이 함께 내는 동작 종단 간 테스트 · 시스템 테스트 · 기능 테스트

확인하는 코드와 실행되는 코드

좁다는 말은 확인하는 코드가 좁다는 뜻입니다. 테스트가 도는 동안 실행되는 코드까지 좁다는 뜻은 아닙니다. 이 소절은 이 차이를 주문 합계 클래스 하나로 봅니다.

아래 주문 합계 클래스는 상품 값을 모두 더합니다. 더한 값은 할인 계산기에 넘겨 할인을 붙입니다. 할인 계산기는 2만 원 이상이면 2천 원을 깎고, 그보다 적으면 받은 값을 돌려줍니다.

Java
class OrderTotal {
    Discount discount = new Discount();

    int total(int... prices) {
        int sum = 0;
        for (int p : prices) sum += p;
        return discount.apply(sum);
    }
}

total 이 값을 더합니다. 마지막 줄에서 할인 계산기의 apply 를 부릅니다. 이제 이 클래스의 더하기가 맞는지 보는 테스트를 씁니다. 자바의 테스트 도구인 JUnit 으로 썼습니다.

Java
@Test
void 상품_값을_모두_더한다() {
    var o = new OrderTotal();
    int t = o.total(3000, 4000); // 7000
    assertEquals(7000, t);
}

total 이 7천 원을 돌려줍니다. 마지막 줄이 그 값이 7천인지 확인합니다. 결과를 확인하는 이 한 줄이 단언입니다.

이 테스트가 도는 동안 할인 계산기도 불립니다. 7천 원은 2만 원이 안 되므로 할인 계산기는 받은 값을 돌려줍니다. 할인 계산기의 코드가 실행되기는 했습니다. 그래도 이 테스트가 확인하는 것은 주문 합계의 더하기 하나입니다.

flowchart TD
    A["테스트"] --> B
    subgraph 확인["테스트가 확인하는 코드"]
        B["주문 합계 · total"]
    end
    B --> C["할인 계산기 · apply"]
    subgraph 실행["실행만 되는 코드"]
        C
    end

그림의 위쪽 상자가 이 테스트의 범위입니다. 아래쪽 상자는 테스트가 돌 때 같이 실행될 뿐입니다. 할인 계산기가 맞는지는 할인 계산기를 겨냥한 다른 좁은 범위 테스트가 확인합니다.

기대는 코드를 두는 두 방법

주문 합계처럼 확인할 부분이 다른 코드에 기대는 일은 흔합니다. 기대는 코드를 테스트에서 어떻게 둘지는 두 갈래로 나뉩니다.

한 갈래는 기대는 코드를 테스트 더블로 바꿔 끼웁니다. 테스트 더블은 테스트에서 진짜 대신 쓰는 가짜입니다. 이렇게 하면 확인할 부분 밖의 코드가 아예 실행되지 않습니다.

다른 갈래는 기대는 코드를 진짜로 둡니다. 할인 계산기처럼 금방 끝나고 돌릴 때마다 같은 값을 내는 코드라면 가짜로 바꿀 까닭이 적습니다. 가짜는 진짜와 다르게 굴 수 있기 때문입니다.

진짜로 두기 어려운 것도 있습니다. 데이터베이스나 네트워크처럼 느리거나 돌릴 때마다 결과가 바뀌는 것은 보통 가짜로 바꿉니다.

어느 갈래를 골라도 범위는 좁습니다. 범위는 무엇이 실행되느냐가 아니라 무엇을 확인하느냐로 정해지기 때문입니다.

테스트 크기라는 다른 축

테스트를 가르는 잣대가 범위 말고 하나 더 있습니다. 테스트 크기는 테스트가 어디서 도느냐로 가릅니다. 프로세스 하나 안에서 도는지, 머신 한 대 안에서 도는지, 여러 머신에 걸쳐 도는지를 봅니다. 코드 줄 수와는 상관이 없습니다.

크기 도는 곳
작은 테스트 프로세스 하나 안
중간 테스트 머신 한 대 안
큰 테스트 여러 머신에 걸쳐도 됨

범위는 무엇을 확인하느냐를 묻습니다. 크기는 어디서 도느냐를 묻습니다. 좁은 범위 테스트는 대개 작은 테스트이지만 늘 그렇지는 않습니다.

예를 들어 주문을 데이터베이스에 저장하는 클래스 하나를 테스트한다고 해 봅시다. 확인하는 것은 그 클래스 하나라서 범위는 좁습니다. 그런데 같은 머신에 진짜 데이터베이스를 띄워 붙이면 프로세스가 둘이 되어 크기는 중간입니다.

종류별 테스트 개수

좁은 범위 테스트는 금방 끝납니다. 결과도 잘 흔들리지 않습니다. 그래서 테스트를 여러 종류로 둘 때 가장 많이 두는 쪽이 됩니다.

좁은 것을 가장 많이, 넓은 것을 가장 적게 두면 개수를 쌓은 모양이 아래가 넓은 삼각형이 됩니다. 이 모양을 테스트 피라미드라고 부릅니다.

구글은 테스트를 범위로 나눠 종류별 개수를 정합니다. 전체 테스트 가운데 좁은 범위를 80% 안팎, 중간 범위를 15%, 넓은 범위를 5%로 두는 것을 목표로 삼습니다.

좁은 범위 테스트가 적고 넓은 범위 테스트가 많으면 삼각형이 뒤집힙니다. 뒤집힌 이 모양이 아이스크림 콘입니다. 테스트 전체가 오래 걸립니다. 깨질 때마다 원인을 찾는 데도 시간이 듭니다.

좁은 범위 테스트가 못 보는 곳

좁은 범위 테스트는 부분 하나씩만 확인합니다. 그래서 부분끼리 이어지는 곳의 잘못은 못 봅니다.

예를 들어 주문 서비스는 금액을 원 단위 정수로 보냅니다. 결제 서비스는 금액이 소수점 붙은 문자열로 온다고 짐작하고 짜여 있습니다. 두 서비스의 좁은 범위 테스트가 각각 전부 통과해도, 둘을 이으면 결제 서비스가 금액을 못 읽습니다.

테스트 더블을 많이 쓸수록 이 틈이 커집니다. 가짜는 테스트를 쓴 사람이 짐작한 대로만 움직입니다. 짐작이 진짜와 다르면 좁은 범위 테스트는 전부 통과하는데 합친 프로그램은 깨집니다. 이 틈을 메우려고 중간 범위와 넓은 범위 테스트를 조금 더 둡니다.

관련 항목

좁은 범위 테스트와 범위로 나뉘는 테스트

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

좁은 범위 테스트를 재는 다른 축

테스트 범위 · 테스트 크기 · 작은 테스트 · 중간 테스트 · 큰 테스트 · 결정성

좁은 범위 테스트가 기대는 코드를 바꿔 끼우는 가짜

테스트 더블 · 스텁 · 목 객체 · 페이크 객체 · 테스트 스파이 · 의존성 주입

좁은 범위 테스트 한 벌을 이루는 구성 요소

단언 · 테스트 케이스 · 테스트 픽스처 · 테스트 스위트 · 테스트 러너 · JUnit

테스트를 종류별로 몇 개씩 둘지 정하는 모양

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

좁은 범위 테스트에서 자주 나는 문제

불안정한 테스트 · 깨지기 쉬운 테스트 · 과도한 모킹 · 테스트 순서 의존성

좁은 범위 테스트가 속하는 상위 분류

QA와 테스트 · 소프트웨어 테스트 · 자동 테스트 · 테스트 자동화

다른 이름: narrow-scoped test · narrow-scope test · narrow-scoped testing · narrow-scoped · 좁은 범위의 테스트