본문 바로가기

통합 테스트와 E2E 테스트 소개

단위·통합·E2E 테스트가 검증하는 연결 범위와 비용을 비교하고 테스트 피라미드에 맞춰 시나리오를 배치합니다.

앞 절에서는 함수/모듈 같은 최소 단위를 검증하는 단위 테스트(Unit Testing)의 중요성과 Jest 기반 작성 방법을 배웠습니다.

단위 테스트는 개별 컴포넌트 신뢰성을 높이고 버그를 빠르게 찾는 데 효과적입니다.

하지만 애플리케이션은 단순히 개별 단위들의 합이 아닙니다.

여러 단위들이 서로 상호작용하고 데이터를 주고받으며, 하나의 큰 기능을 완성합니다.

이때, 각 단위가 개별적으로는 문제가 없더라도, 서로 연결되었을 때 예상치 못한 문제가 발생할 수 있습니다.

예를 들어, 로그인 컴포넌트와 사용자 정보 표시 컴포넌트가 각각 단위 테스트를 통과했더라도, 로그인 성공 후 사용자 정보가 제대로 전달되어 표시되는지 여부는 단위 테스트만으로는 보장하기 어렵습니다.

이 문제를 해결하고 더 큰 기능 흐름을 검증하려면 통합 테스트(Integration Testing)와 E2E(End-to-End) 테스트가 필요합니다.

이번 장에서는 두 테스트의 개념, 목적, 적용 시나리오, 주요 도구를 간략히 정리합니다.

앞 절의 describe, test, expect와 모듈 임포트를 먼저 익혀 둡니다. 여기서 의존성은 어떤 코드가 동작하기 위해 호출하거나 데이터를 받아야 하는 다른 코드입니다. 스텁(stub)은 미리 정한 응답을 돌려주는 대역이고, 모의 객체(mock)는 호출 여부나 전달값도 검사할 수 있는 대역입니다. 도구에서 두 용어를 넓게 쓰기도 하므로, 이름보다 실제로 실행한 연결과 대체한 연결을 기록하는 것이 중요합니다.

위험으로 고르는 테스트 범위

FLOWCHART · WEB PLATFORM CONTRACT

위험으로 고르는 테스트 범위

먼저 실패 영향과 원인 진단 비용을 기록하고, 검증 질문이 격리한 동작·협력자 계약·전체 사용자 여정 중 어디에 걸리는지에 따라 주 테스트 범위를 고른다.

위험으로 고르는 테스트 범위 실패 영향과 진단 비용을 먼저 평가하고 검증 질문의 경계에 따라 unit, integration, E2E를 주 범위로 선택한 뒤 위험 포트폴리오로 조합하는 흐름 검증 질문 + 위험 평가실패 영향 · 진단 비용 · 변경 빈도무엇을 함께 실행해야질문을 확인할 수 있나?Unit격리한 규칙 · 빠른 진단Integration모듈 · API · DB 계약E2E핵심 사용자 여정위험 포트폴리오로 함께 배치빠른 하위 범위는 넓게 · 비싼 상위 범위는 실패 영향이 큰 경로에 집중ISOLATEDCOLLABORATORFULL PATH
위험으로 고르는 테스트 범위실패 영향·진단 비용·변경 빈도를 먼저 평가한다. 함께 실행해야 할 연결에 따라 Unit, Integration, E2E의 세 독립 분기로 나누고 위험 포트폴리오에 합류해 조합한다. 왼쪽 분기 선의 세 화살표는 독립 범위를 고르고 오른쪽 합류 선은 세 범위를 함께 포트폴리오에 배치한다. 세 범위를 차례로 실행한다는 뜻이 아니다. ISOLATED COLLABORATOR FULL PATH 검증 질문 +위험 평가실패 영향 ·진단 비용 ·변경 빈도 무엇을함께실행해야질문을확인할수 있나? Unit격리한 규칙 ·빠른 진단 Integration모듈 · API ·DB 계약 E2E핵심 사용자 여정 위험포트폴리오로함께 배치빠른 하위 범위는넓게 ·비싼 상위 범위는실패 영향이 큰경로에 집중

세 범위는 상호 배타적 종류가 아니다. 같은 기능에 여러 범위를 조합할 수 있다. E2E의 전체 경로는 통제된 테스트 환경에서 실행하며 실제 운영 환경을 뜻하지 않는다.


테스트 피라미드: 다양한 테스트 레벨의 조화

소프트웨어 테스팅에는 여러 레벨이 있으며, 이들은 일반적으로 테스트 피라미드(Test Pyramid)라는 개념으로 설명됩니다.

  • 단위 테스트 (Unit Test): 피라미드의 하단입니다. 함수·메서드 같은 작은 규칙을 격리하여 검사하므로 대체로 빠르게 많이 실행할 수 있습니다.
  • 통합 테스트 (Integration Test): 중간입니다. 여러 모듈의 상호작용과 데이터 전달을 검사합니다. 실제 데이터베이스를 포함하는지 등 연결 범위에 따라 실행 비용이 달라집니다.
  • E2E 테스트 (End-to-End Test): 상단입니다. 브라우저에서 핵심 사용자 흐름을 시작하여 테스트 대상 시스템의 끝 결과까지 확인합니다. 준비·실행·실패 진단 비용이 커지는 경향이 있어 중요한 흐름에 집중합니다.

테스트 피라미드는 하단으로 갈수록 테스트의 개수가 많아지고, 상단으로 갈수록 개수가 적어지는 형태를 가집니다.

이 모양은 빠른 검사를 넓게 두고 비싼 검사를 핵심 위험에 배치하자는 출발점입니다. 개수 비율이나 실행 속도 순서를 무조건 강제하는 법칙은 아닙니다. UI와 상태 연결이 중심인 앱은 통합 테스트의 비중이 높을 수 있습니다. 위 그림처럼 검증 질문에 필요한 연결을 고른 뒤, 실제 실행 시간과 실패 원인을 좁히는 데 드는 비용으로 조합을 조정합니다.


통합 테스트 (Integration Testing)

통합 테스트는 두 개 이상의 모듈 또는 컴포넌트가 함께 작동할 때 발생하는 상호작용과 데이터 흐름을 검증하는 테스트입니다.

즉, 단위 테스트에서 검증한 개별 기능들이 서로 연결되었을 때도 올바르게 동작하는지 확인합니다.

통합 테스트의 목적 및 필요성

  • 모듈 간의 인터페이스 검증: 서로 다른 모듈이 데이터를 주고받는 방식이 올바른지 확인합니다.
  • 데이터 흐름 검증: 한 모듈의 출력이 다른 모듈의 입력으로 사용될 때, 데이터가 올바르게 전달되고 처리되는지 확인합니다.
  • 서브시스템 결합 확인: 데이터베이스, 외부 API 등의 의존성과 연동이 잘 되는지 부분적으로 검증합니다. (단, 실제 외부 시스템이 아닌 모의(Mock) 객체를 사용하여 테스트하기도 함)

단위 테스트와의 차이점

  • 단위 테스트: 작은 공개 동작을 격리하여 테스트합니다. 외부 의존성이 있으면 모의 객체나 스텁으로 통제할 수 있지만, 순수 계산 함수처럼 대역이 필요 없는 경우도 있습니다.
  • 통합 테스트: 실제 컴포넌트들이 서로 연결된 상태에서 테스트합니다. 의존성도 실제 의존성을 사용하거나, 최소한의 모의 객체로 대체하여 실제 환경에 가깝게 테스트합니다.

통합 테스트 시나리오 예시

  • 사용자 로그인 기능: 로그인 폼 컴포넌트와 인증 로직 모듈, API 호출 서비스가 함께 작동하여 사용자가 성공적으로 로그인하고 인증 토큰을 받는지 확인. (여기서 API 호출은 실제 서버가 아닌 모의 서버나 Mock API를 사용할 수 있음)
  • 장바구니 추가: 상품 선택 컴포넌트와 장바구니 상태 관리 모듈이 연동되어 상품이 장바구니에 올바르게 추가되고 총 가격이 업데이트되는지 확인.
  • 데이터베이스 연동: 데이터 저장 함수와 데이터베이스 드라이버가 연동되어 특정 데이터가 데이터베이스에 올바르게 저장되는지 확인. (실제 개발용 데이터베이스를 사용할 수 있음)

통합 테스트 도구 (간략)

통합 테스트는 특정 도구에 얽매이기보다는 어떤 범위까지 테스트할 것인지에 따라 Jest와 같은 단위 테스트 프레임워크를 확장해서 사용하거나, 더 나아가 Cypress, Playwright 같은 E2E 테스트 도구의 일부 기능을 활용하기도 합니다.

  • Jest (확장): jest.mock()을 사용하여 외부 의존성을 부분적으로 모의 처리하고, 여러 모듈을 함께 임포트하여 테스트합니다.
  • Testing Library: 특정 프레임워크(React, Vue 등)의 컴포넌트 통합 테스트에 유용하며, 사용자 관점에서 DOM에 접근하여 테스트합니다.
  • MSW (Mock Service Worker): 네트워크 요청을 가로채서 모의 응답을 제공하여, 실제 백엔드 없이도 프론트엔드의 네트워크 관련 통합 테스트를 수행할 수 있게 합니다.

Testing Library는 DOM을 사용자가 찾는 방식에 가깝게 조회하도록 돕습니다. 버튼은 역할과 접근 가능한 이름, 입력은 연결된 레이블로 찾는 방식을 우선합니다. DOM에서 컴포넌트를 검사했다는 사실만으로 실제 브라우저의 배치·터치·전체 서버 연결을 검증한 것은 아닙니다. Testing Library 조회 원칙

MSW를 썼다면 “UI → 요청 생성 → 정해진 응답 처리”를 검사한 것입니다. 그 모의 응답을 실제 서버가 반환하는지, 서버가 DB에 쓰는지는 별도 검증 대상입니다. MSW 공식 안내

작은 연결을 직접 검증하기

앞 절의 Jest·Babel 연습 설정을 그대로 사용합니다. 다음 두 실제 모듈은 장바구니 금액 계산과 표시 문자열 생성을 연결합니다. 입력은 숫자 가격과 양의 정수 수량이며, 세금·배송비·할인·잘못된 입력 처리는 이 예제 범위에 없습니다.

// src/cart.js
export function cartTotal(items) {
    return items.reduce((sum, item) => sum + item.price * item.quantity, 0);
}
// src/cart-summary.js
import { cartTotal } from './cart';

export function cartSummary(items) {
    const quantity = items.reduce((sum, item) => sum + item.quantity, 0);
    return `${quantity}개 · ${cartTotal(items)}원`;
}
// src/cart-summary.test.js
import { cartSummary } from './cart-summary';

test('실제 계산 결과와 총 수량을 표시 문자열에 전달한다', () => {
    const items = [
        { price: 2000, quantity: 2 },
        { price: 12000, quantity: 1 },
    ];
    expect(cartSummary(items)).toBe('3개 · 16000원');
});

기대값은 2000 × 2 + 12000 × 1 = 16000, 수량은 2 + 1 = 3으로 손으로 구합니다. 여기서는 cartTotal을 mock으로 바꾸지 않았으므로 두 모듈의 실제 연결을 확인합니다. 상품 종류 수인 items.length를 총 수량으로 잘못 쓰면 2개가 출력되어 이 테스트가 실패합니다. 이 검사는 DOM 표시·클릭·저장 API까지 확인하지는 않습니다.


E2E 테스트 (End-to-End Testing)

E2E (End-to-End) 테스트는 사용자 입력부터 최종 결과까지 정의한 시스템 경계가 연결되어 작동하는지 검증합니다. 예를 들어 브라우저·테스트용 백엔드·테스트용 DB를 연결하고 주문이 저장되는 흐름을 확인합니다. 결제사 같은 제어할 수 없는 외부 서비스는 테스트용 환경이나 대역을 사용할 수 있으며, 대역 밖의 실제 연결까지 통과했다고 말하지 않습니다.

브라우저 자동화로 UI를 검사해도 모든 API를 가로채 모의 응답만 제공했다면 실제 백엔드·DB 연동은 확인되지 않습니다. 테스트 이름에 E2E라고 적는 것보다 그 경계를 설명해야 합니다. Playwright의 외부 의존성·데이터 통제 안내

E2E 테스트의 목적 및 필요성

  • 사용자 시나리오 검증: 핵심 비즈니스 흐름이 실제 환경에서 문제없이 작동하는지 확인합니다. (예: 회원가입 -> 로그인 -> 상품 검색 -> 장바구니 추가 -> 결제 완료와 같은 전체 흐름)
  • 시스템 통합 검증: 테스트 경계에 포함한 프론트엔드·백엔드·데이터베이스의 연결과 결과를 확인합니다.
  • 배포 전 핵심 흐름 검증: 실제 사용자에게 제공하기 전에 중요한 사용자 흐름의 회귀를 확인합니다. 몇 개의 E2E 통과만으로 접근성·성능·보안까지 모두 보장하지는 않습니다.

단점

  • 느린 실행 속도: 실제 브라우저를 띄우고, 네트워크 요청을 보내고, UI를 렌더링하는 등 모든 과정을 시뮬레이션하므로 실행 시간이 가장 오래 걸립니다.
  • 높은 비용: 테스트 작성, 유지보수, 실행 환경 설정 등에 많은 시간과 노력이 필요합니다.
  • 불안정성: 네트워크 지연, 외부 서비스의 일시적인 문제, UI 변경 등으로 인해 실패하지 않아야 할 테스트가 실패하는 플래키(flaky) 테스트가 발생하기 쉽습니다.

E2E 테스트 시나리오 예시

  • 회원 가입 및 로그인 흐름: 사용자가 회원가입 폼을 채우고 제출하여 계정을 생성한 후, 해당 계정으로 로그인하여 대시보드에 접근하는 전 과정을 테스트합니다.
  • 상품 구매 프로세스: 사용자가 상품을 검색하고, 장바구니에 추가하며, 결제 정보를 입력하고, 주문을 완료하는 전체 흐름을 테스트합니다.
  • 관리자 페이지 기능: 관리자가 로그인하여 사용자 목록을 조회하고, 특정 사용자의 권한을 변경한 후, 변경된 권한이 적용되었는지 확인하는 흐름을 테스트합니다.

E2E 테스트 도구 (간략)

E2E 테스트는 주로 실제 브라우저를 자동화하여 사용자 상호작용을 시뮬레이션하는 도구들을 사용합니다.

  • Cypress: 실제 브라우저에서 상호작용을 자동화하고 실행 과정을 관찰할 수 있습니다. 도구 선택만으로 안정성이 보장되지는 않으므로 데이터·외부 요청·대기를 통제해야 합니다.
  • Playwright: Microsoft에서 개발한 도구로, Chromium, Firefox, WebKit 등 다양한 브라우저를 지원하며, Node.js, Python 등 여러 언어로 테스트를 작성할 수 있습니다.
  • Selenium: WebDriver를 이용한 웹 자동화 도구입니다. 여러 언어와 브라우저로 사용자 흐름을 작성할 수 있습니다.

같은 장바구니를 E2E로 확인한다면

다음은 앞의 두 함수를 사용하는 가상의 실습 앱에 대한 시나리오입니다. 이 교재 사이트에 해당 장바구니 서버가 있다는 뜻은 아닙니다.

구간고정할 조건 또는 동작통과 판정
준비다른 테스트와 겹치지 않는 테스트 계정, 빈 장바구니, 상품 A 2000원·B 12000원, 해당 빌드시작 수량과 금액이 0이며 상품 데이터가 같음
입력브라우저에서 A 두 개와 B 한 개를 추가접근 가능한 장바구니 요약에 3개·16000원이 표시됨
저장 연결실제 테스트 백엔드·DB를 사용하고 저장 완료 뒤 새로고침저장한 수량·금액이 복원됨
마무리이번 테스트가 만든 데이터와 로그인 상태를 정리다른 테스트를 단독 실행해도 같은 초기 조건을 얻음

버튼 클릭이 끝났다는 사실 대신 최종 요약과 복원 상태를 단언합니다. Playwright의 locator와 재시도하는 assertion으로 관찰 가능한 상태를 기다릴 수 있으며, 무조건 1초씩 기다리는 코드는 서버가 느리면 불안정해집니다. page의 새 브라우저 컨텍스트가 쿠키·스토리지를 분리해도 공유 서버 DB의 장바구니가 자동으로 초기화되지는 않습니다. Playwright 테스트 격리와 locator 안내

범위와 실패를 구분하는 연습

장바구니 금액이 틀렸다고 가정합니다. ① cartTotal만 호출, ② 두 모듈을 실제로 연결, ③ 브라우저에서 상품을 추가하되 API는 모의 응답, ④ 실제 테스트 서버·DB로 추가 후 새로고침을 각각 실행했습니다. 각 검사가 찾을 수 있는 결함과 찾지 못하는 결함을 하나씩 적으세요. ③이 통과하고 ④만 실패했다면 다음에 볼 연결도 고르세요.

범위별 풀이

①은 곱셈·합계 규칙을 확인하지만 표시 문자열 전달은 놓칩니다. ②는 계산과 문자열의 연결을 확인하지만 브라우저 입력은 놓칩니다. ③은 UI 입력과 정해진 응답 처리를 확인하지만 실제 API·DB 저장은 놓칩니다. ④는 정의한 브라우저→서버→저장→복원 경로를 확인하지만 테스트에 포함하지 않은 외부 서비스나 다른 사용자 흐름은 남습니다.

③ 통과·④ 실패만으로 서버 버그를 확정하지 않습니다. 실제 요청 본문·응답, 테스트 데이터·계정, 저장 완료 시점, DB의 읽기·쓰기 경로를 차례로 대조합니다. 먼저 준비 조건이 같은지 확인하고, 저장 실패와 복원 실패를 분리하면 원인 범위를 좁힐 수 있습니다.


통합·E2E 테스트 정리

핵심은 테스트 피라미드에서 비용 대비 신뢰도가 높은 조합을 선택하는 것입니다.

이번 장에서는 단위 테스트를 넘어 애플리케이션의 더 큰 그림을 검증하는 통합 테스트(Integration Testing)와 E2E 테스트(End-to-End Testing)에 대해 학습했습니다.

테스트 피라미드 관점에서 각 테스트 레벨의 역할을 구분했습니다.

통합 테스트는 여러 모듈의 상호작용과 데이터 흐름을 검증하고, E2E 테스트는 실제 사용자 관점의 전체 흐름을 확인하지만 실행 속도와 유지보수 비용을 함께 고려해야 합니다.

테스트 전략은 단위 테스트, 통합 테스트, E2E 테스트의 역할을 나누어 설계해야 합니다.

대부분의 비즈니스 로직은 빠른 단위 테스트로 확인하고, 핵심 기능의 통합과 사용자 흐름은 통합 테스트와 E2E 테스트로 검증합니다.

이 구조는 변경 영향과 회귀 위험을 단계별로 드러냅니다.

통합 테스트와 E2E 테스트는 테스트가 덮는 경계의 크기가 다르므로, 실패했을 때 원인을 좁힐 수 있는 범위를 기준으로 선택합니다.