통합 테스트

Integration Test

방법

여러 구성 요소를 실제로 이어 붙인 상태에서 그 사이가 제대로 맞물리는지 확인하는 테스트입니다.

등장 배경

코드를 확인하는 가장 기본적인 방법은 조각 하나를 떼어 놓고 값을 넣어 보는 것입니다. 할인 금액을 계산하는 함수에 1만 원과 10퍼센트를 넣어 9천 원이 나오면 그 함수는 제 몫을 합니다. 이렇게 조각 하나만 보는 확인을 단위 테스트라고 하고, 한 건이 1000분의 1초 만에 끝나 수천 개를 모아 돌려도 1분이 걸리지 않습니다.

문제는 조각이 전부 멀쩡한데 이어 붙이면 깨지는 일이 흔하다는 것입니다. 계산 함수는 숫자를 9000이라는 정수로 돌려주는데, 그 값을 받아 저장하는 데이터베이스의 칸은 소수점 두 자리까지 받도록 되어 있습니다. 각자 자기 규격대로 돌아가고 각자의 테스트도 통과하지만, 둘을 연결하면 금액이 90.00원으로 저장됩니다.

이런 고장은 회의실에서 늘 같은 모양으로 나타났습니다. 결제가 안 된다는 문의가 들어오고, 결제 담당 개발자가 "제 쪽은 테스트 다 통과했는데요" 라고 말하고, 저장 담당 개발자도 똑같이 말합니다. 둘 다 거짓말이 아닙니다. 아무도 둘 사이를 확인하지 않았을 뿐입니다.

통합 테스트는 그 사이를 확인 대상으로 끌어올린 것입니다. 조각을 떼어 놓지 않고 실제로 연결한 채 돌려서, 주고받는 값의 모양과 순서와 실패 처리가 서로 맞는지를 봅니다. 확인하는 것이 조각의 안쪽이 아니라 조각과 조각이 맞닿는 이음매라는 점이 다릅니다.

사용 절차

붙일 범위를 정하는 것부터 시작합니다. 전부를 붙이면 E2E 테스트가 되고 아무것도 안 붙이면 단위 테스트가 되므로, 실제로 자주 어긋나는 두세 요소만 고르는 것이 요령입니다.

  1. 이음매를 고릅니다. 주문 처리 코드와 데이터베이스, 또는 회원 가입 코드와 메일 발송 모듈처럼 값이 실제로 건너가는 구간을 잡습니다.
  2. 바깥 세계를 잘라 냅니다. 테스트를 돌릴 때마다 카드사에 진짜 요청을 보낼 수는 없으니, 늘 성공이라고만 답하는 가짜를 세워 둡니다. 이 가짜를 목이라고 합니다. 우리가 확인하려는 이음매는 진짜로 두고, 남의 서버에 기대는 부분만 가짜로 바꿉니다.
  3. 시작 상태를 깔아 둡니다. 사용자 두 명과 주문 세 건이 이미 있는 상태를 매번 손으로 만들지 않고 한 번 적어 두고 불러 씁니다. 이렇게 미리 준비한 데이터를 픽스처라고 합니다.
  4. 이어 붙인 채로 돌리고 결과를 봅니다. 함수가 무엇을 돌려줬는지가 아니라, 데이터베이스에 9000원이 제대로 들어갔는지처럼 건너간 뒤의 상태를 확인합니다.
  5. 뒷정리를 합니다. 테스트가 만든 데이터를 지우거나 되돌려 놓습니다. 이 단계를 빼면 어제 돌린 테스트가 남긴 주문 때문에 오늘 테스트가 실패합니다.

이 묶음은 변경을 합칠 때마다 자동으로 돌게 걸어 둡니다. 코드를 올릴 때마다 검증이 자동으로 실행되는 방식을 지속적 통합이라고 하고, 통합 테스트는 대개 그 안에서 단위 테스트 다음 차례로 돕니다.

적합한 상황과 한계

값이 두 개 이상의 요소 사이를 건너가는 자리에 씁니다. 코드가 데이터베이스에 쓰는 자리, 외부 창구를 호출하는 자리, 한 서비스가 다른 서비스를 부르는 자리가 대표적입니다. 반대로 계산식 하나의 정확성처럼 한 조각 안에서 끝나는 확인은 단위 테스트가 더 빠르고 정확합니다.

기능별로 서비스를 쪼개 둔 구조에서 특히 값이 올라갑니다. 조각이 많을수록 이음매도 많아지고, 이음매가 많을수록 각자 멀쩡한데 전체가 안 도는 상황이 잦아지기 때문입니다.

한계는 세 가지입니다. 첫째, 느립니다. 데이터베이스를 띄우고 데이터를 깔았다가 지우는 과정이 붙어서 한 건에 0.5초에서 몇 초가 걸립니다. 단위 테스트 2천 개보다 통합 테스트 200개가 더 오래 걸리는 일이 보통입니다. 둘째, 고장 원인을 정확히 짚어 주지 않습니다. 실패했다는 사실은 알려 주지만 어느 쪽이 잘못인지는 사람이 다시 들어가 봐야 합니다. 셋째, 불안정해지기 쉽습니다. 실행 순서나 남은 데이터에 기대기 시작하면 같은 코드에서 어떤 날은 통과하고 어떤 날은 실패하는 플레이키 테스트가 됩니다.

그래서 수를 늘리는 대신 자리를 고릅니다. 단위 테스트를 수천 개 깔아 두고, 통합 테스트는 실제로 값이 건너가는 구간 수십 개만 두는 비율이 흔합니다.

실무 용례

"단위는 다 초록인데 통합에서 걸렸어요. 주문 저장 쪽 같습니다."

조각마다의 확인은 통과했고 이음매에서 실패했으니 두 요소가 맞닿는 지점을 보고 있다는 뜻입니다.

"이건 통합 테스트로 잡았어야 하는 건데 그 구간이 비어 있었네요."

사고가 난 이음매에 애초에 테스트가 없었다는 인정이고, 다음 작업으로 그 자리를 채우겠다는 말입니다.

"통합 테스트가 3분 넘어가서 병렬로 쪼갤게요."

검증 시간이 길어져 개발자들이 기다리게 됐으니 나눠 돌리겠다는 뜻입니다.

페이지덱에서는 문서 저장 기능을 고칠 때 이 이야기가 나옵니다. 태오가 자동 저장 주기를 고친 뒤 단위 테스트를 돌리면 전부 초록이 뜨는데, 통합 테스트에서 한 건이 빨갛게 남습니다. 저장 요청이 1초 안에 두 번 들어오면 두 번째 요청이 첫 번째가 만든 기록을 덮어써 버리는 경우입니다.

이 고장은 저장 코드만 봐서는 보이지 않습니다. 코드와 데이터베이스가 실제로 이어진 상태에서 요청을 연달아 넣어야 드러납니다. 태오가 그 구간을 고치고 나면 같은 테스트가 초록으로 바뀌고, 그 테스트는 그대로 남아 다음에 같은 자리를 건드리는 사람을 막아 줍니다.

흔한 오해

통합 테스트를 단위 테스트의 상위 버전으로 읽는 경우가 가장 많습니다. 더 넓게 보니 더 좋은 테스트처럼 느껴지기 때문입니다. 하지만 둘은 층이 다를 뿐 우열이 아닙니다. 넓게 볼수록 현실에 가깝지만 느리고 원인을 짚기 어려워집니다. 이걸 우열로 읽고 통합 테스트만 수백 개 깔면 한 바퀴 도는 데 20분이 걸리고, 그쯤 되면 팀은 결과를 기다리지 않고 합치기 시작하며, 테스트는 경고 기능을 잃습니다.

진짜 환경에 가까울수록 좋다고 보는 것도 같은 문제입니다. 실제 카드사에 붙여 돌리면 더 확실할 것 같지만, 그러면 상대 서버가 느린 날 우리 테스트가 실패하고 결제 수수료까지 나갑니다. 흉내만 내는 가짜를 쓰는 이유는 게을러서가 아니라 우리가 확인하려는 이음매만 남기기 위해서입니다. 바깥까지 진짜로 붙이는 확인은 배포 직전에 몇 건만 따로 돌립니다.

자주 헷갈리는 용어

용어무엇을 붙여 놓고 보는가통합 테스트와의 차이
단위 테스트아무것도 붙이지 않고 조각 하나만조각 안쪽의 논리를 봅니다. 1000분의 1초로 빠르고 실패하면 원인이 바로 그 조각이지만, 조각끼리 어긋나는 고장은 잡지 못합니다
E2E 테스트브라우저까지 전부사용자가 하는 대로 로그인부터 결제까지 눌러 봅니다. 가장 현실에 가깝지만 한 건에 10초씩 걸리고 화면 문구 하나만 바뀌어도 깨집니다

같이 보면 좋은 페이지

  • 테스트

    이 테스트가 어떤 층들 사이에 놓이는지 전체 지형을 봅니다

  • 단위 테스트

    바로 아래층이라 둘을 나란히 보면 경계가 분명해집니다

마지막 업데이트 2026-09-16