V모델로 이해하는 테스트 레벨과 테스트 방법
1. V모델 개념 이해하기

V모델은 개발 단계와 테스트 단계를 서로 대응시켜 보는 소프트웨어 개발 및 테스트 모델입니다. 일반적인 개발 흐름에서는 요구사항을 분석하고, 설계하고, 구현한 뒤 테스트를 수행합니다.

이 흐름은 이해하기 쉽지만, 테스트를 구현 이후의 활동으로만 생각하게 만들 수 있습니다. V모델은 이 관점을 조금 다르게 봅니다.
개발 단계에서 만들어지는 산출물은 나중에 대응되는 테스트 단계에서 검증되어야 하며, 각 테스트의 계획이나 테스트 케이스도 해당 개발 단계에서 미리 준비해야 한다고 봅니다.
즉, V모델의 핵심은 다음과 같습니다.
▸ 각 테스트의 계획과 테스트 케이스는 대응되는 개발 단계에서 미리 작성한다.
▸ 구현 이후에는 미리 준비한 테스트를 해당 테스트 단계에서 수행한다.
▸ 개발 산출물과 테스트 산출물을 연결하여 요구사항 누락이나 검증 누락을 줄인다.
🔷 개발 단계와 테스트 단계의 대응 관계
V모델의 왼쪽은 개발을 위한 분석과 설계 단계이며, 오른쪽은 이를 검증하는 테스트 단계입니다.
| 개발 단계 | 정의하는 내용 | 대응 테스트 | 검증 관점 |
| 요구사항 분석 | 사용자 요구사항, 비즈니스 조건 | 인수 테스트 | 사용자가 요구한 결과를 만족하는가? |
| 시스템 설계 | 전체 구조, 기능 흐름, 비기능 요구사항 | 시스템 테스트 | 시스템이 요구사항대로 동작하는가? |
| 아키텍처 설계 | 컴포넌트 구조, 인터페이스, 연동 방식 | 통합 테스트 | 모듈들이 올바르게 연결되는가? |
| 모듈 설계 | 함수, 클래스, 메서드의 세부 로직 | 단위 테스트 | 개별 코드 단위가 의도대로 동작하는가? |
예를 들어 로그인 기능을 V모델 관점에서 보면 다음과 같이 정리할 수 있습니다.
| 개발 산출물 | 예시 | 대응 테스트 |
| 요구사항 분석 | 사용자는 이메일로 로그인할 수 있어야 한다. | 인수 테스트에서 실제 사용자가 이메일로 로그인할 수 있는지 확인 |
| 시스템 설계 | 로그인 성공 시 메인 화면으로 이동하고, 실패 시 오류 메시지를 표시한다. | 시스템 테스트에서 로그인 전체 흐름이 요구사항대로 동작하는지 확인 |
| 아키텍처 설계 | LoginController가 AuthService를 호출하고, AuthService가 UserRepository를 사용한다. | 통합 테스트에서 컴포넌트 간 데이터 전달과 호출이 올바른지 확인 |
| 모듈 설계 | validateEmail() 함수는 이메일 형식을 검증한다. | 단위 테스트에서 함수의 반환값과 예외 처리를 확인 |
🔷 테스트 계획은 언제 작성하는가?
V모델에서 중요한 점은 테스트가 구현 이후에 갑자기 시작되는 활동이 아니라는 것입니다. 구현 후에는 테스트를 '수행'하지만, '계획과 케이스'는 대응되는 개발 단계에서 미리 준비합니다.
| 개발 단계 | 계획 수립 | 구현후 테스트 |
| 요구사항 분석 | 인수 테스트 계획 수립 | 인수 테스트 |
| 시스템 설계 | 시스템 테스트 계획 수립 | 시스템 테스트 |
| 아키텍처 설계 | 통합 테스트 계획 수립 | 통합 테스트 |
| 모듈 설계 | 단위 테스트 케이스 작성 | 단위 테스트 |
🔷 V모델이 강조하는 '추적성(Traceability)'
V모델은 단순히 순서도를 그리기 위한 모델이 아닙니다. 핵심은 개발 산출물과 테스트 산출물의 연결 고리입니다.
이 연결(추적성)이 명확하면 다음과 같은 질문에 바로 답할 수 있습니다.
▸ 이 요구사항은 어떤 테스트로 검증되는가?
▸ 이 설계 내용이 테스트 케이스에 누락되지 않았는가?
▸ 기능 변경 시 어떤 테스트를 다시 수행해야 하는가?
▸ 어떤 기준으로 이 프로젝트의 '완료'를 판단할 것인가?
예를 들어 요구사항이 변경되었는데 인수 테스트 케이스가 수정되지 않았다면, 나중에 변경 전 기준으로 제품을 검사할 수 있습니다. 반대로 테스트 케이스는 변경되었지만 요구사항 문서가 수정되지 않았다면, 테스트 결과와 실제 요구사항 사이에 불일치가 생길 수 있습니다.
V모델은 이런 문제를 방지하기 위해 요구사항, 설계, 구현, 테스트를 서로 연결해서 관리하는 것을 강조합니다.
🔷 V모델의 장점과 한계
V모델의 장점은 개발 단계별 산출물과 테스트 단계별 산출물이 명확히 대응된다는 점입니다. 요구사항, 설계, 테스트 기준이 연결되므로 검증 누락을 줄일 수 있고, 변경이 발생했을 때 영향 범위를 추적하기 쉽습니다.
주요 장점은 다음과 같습니다.
▸ 요구사항과 테스트 간 연결이 명확해진다.
▸ 테스트 계획을 초기에 수립할 수 있다.
▸ 각 개발 단계의 산출물을 어떤 테스트로 검증할지 분명해진다.
▸ 완료 기준과 품질 기준을 비교적 명확하게 정의할 수 있다.
▸ 기능 변경 시 재수행해야 할 테스트 범위를 추적하기 쉽다.
하지만 V모델에도 한계가 있습니다.
▸ 요구사항이 자주 바뀌는 프로젝트에서는 문서와 테스트 계획을 계속 수정해야 한다.
▸ 초반에 요구사항과 설계를 상세히 정의해야 하므로 애자일 방식보다 유연성이 떨어질 수 있다.
▸ 구현 후반부에 본격적인 테스트가 집중되면 문제 발견이 늦어질 수 있다.
▸ 문서와 테스트 산출물 관리가 제대로 되지 않으면 형식적인 프로세스가 될 수 있다.
따라서 V모델은 요구사항과 검증 기준이 비교적 명확한 프로젝트에서 특히 효과적입니다. 반대로 요구사항 변화가 잦은 프로젝트에서는 V모델의 추적성 개념은 유지하되, 테스트 자동화와 반복적인 검증 방식을 함께 사용하는 것이 좋습니다.
2. 단위 테스트
단위 테스트는 가장 작은 코드 단위를 독립적으로 검증하는 테스트입니다. 전체 시스템을 실행하지 않고 함수, 메서드, 클래스와 같은 작은 단위가 의도한 대로 동작하는지 확인합니다.
예를 들어 다음과 같은 기능들이 단위 테스트의 대상이 될 수 있습니다.
| 테스트 대상 | 설명 |
| validatePassword() | 비밀번호 형식이 올바른지 검증 |
| calculateDiscount() | 할인 금액 또는 할인율 계산 |
| createJwtToken() | JWT 토큰 생성 로직 검증 |
| UserService.findByEmail() | 이메일 기반 사용자 조회 로직 검증 |
단위 테스트의 핵심은 테스트 대상만 분리하여 빠르고 정확하게 검증하는 것입니다.
1) 화이트박스 기반 테스트
단위 테스트는 코드의 내부 구조와 동작 방식을 알고 작성하는 경우가 많습니다. 개발자가 직접 작성한 조건문, 반복문, 예외 처리, 반환값 등을 기준으로 테스트 케이스를 구성할 수 있습니다.
주로 다음 내용을 확인합니다.
| 확인 항목 | 설명 |
| 조건문 분기 | if, else, switch 문이 의도한 경로로 동작하는지 확인 |
| 예외 처리 | 잘못된 입력이나 오류 상황에서 예외가 정상적으로 처리되는지 확인 |
| 반복문 경계 | 반복문이 시작값, 종료값, 경계 조건에서 올바르게 동작하는지 확인 |
| 반환값 | 함수나 메서드의 결과값이 기대한 값과 일치하는지 확인 |
@Test
void 비밀번호가_8자_미만이면_false를_반환한다() {
assertFalse(validatePassword("abc12"));
}
2) Mock / Stub을 통한 의존성 격리
단위 테스트는 테스트 대상 코드만 검증하는 것이 중요합니다. 따라서 DB, 외부 API, 파일 시스템처럼 외부 의존성이 있는 경우 실제로 호출하지 않고 Mock 또는 Stub 같은 테스트 대역으로 대체합니다.
Mock과 Stub은 테스트 대상 외부의 의존성을 격리하기 위해 사용하는 가짜 객체입니다.
예를 들어 로그인 기능을 테스트한다고 가정하면, 실제 DB나 토큰 발급 시스템을 호출하지 않고 다음과 같이 대체할 수 있습니다.
| 실제 의존성 | 대체 방식 |
| UserRepository | Mock 객체로 대체하여 가짜 사용자 정보 반환 |
| TokenProvider | Mock 객체로 대체하여 가짜 토큰 반환 |
이렇게 하면 외부 시스템의 상태와 관계없이 로그인 로직 자체만 안정적으로 테스트할 수 있습니다.
@Test
void 로그인에_성공하면_토큰을_반환한다() {
when(userRepository.findByEmail("test@example.com"))
.thenReturn(Optional.of(user));
when(tokenProvider.createToken(user))
.thenReturn("fake-jwt-token");
String token = authService.login("test@example.com", "password123");
assertEquals("fake-jwt-token", token);
}
3) 경계값 테스트
경계값 테스트는 입력값의 최소값, 최대값, 기준값 주변을 집중적으로 확인하는 방법입니다. 오류는 주로 경계 지점에서 많이 발생하기 때문에 단위 테스트에서 매우 중요합니다.
예를 들어 비밀번호의 최소 길이가 8자라면 다음과 같이 테스트할 수 있습니다.
@Test
void 비밀번호가_7자이면_false를_반환한다() {
assertFalse(validatePassword("1234567"));
}
@Test
void 비밀번호가_8자이면_true를_반환한다() {
assertTrue(validatePassword("12345678"));
}
@Test
void 비밀번호가_9자이면_true를_반환한다() {
assertTrue(validatePassword("123456789"));
}
이 경우 중요한 값은 단순히 “짧은 비밀번호”와 “긴 비밀번호”가 아닙니다. 기준값인 8자를 중심으로 7자, 8자, 9자를 확인하는 것이 핵심입니다.
4) 자동화 테스트
단위 테스트는 기능 개발, 코드 수정, 리팩터링 과정에서 반복적으로 실행됩니다. 따라서 대부분의 단위 테스트는 자동화하여 사용합니다.
주요 언어별 테스트 도구는 다음과 같습니다.
| 언어 | 대표 도구 |
| Java | JUnit, Mockito |
| JavaScript / TypeScript | Jest, Vitest |
| Python | pytest, unittest |
| C# | xUnit, NUnit |
자동화 테스트를 구성하면 개발자는 코드를 변경한 후 테스트를 실행하여 기존 기능이 정상적으로 유지되는지 쉽게 확인할 수 있습니다.
3. 통합 테스트
통합 테스트는 여러 모듈이나 컴포넌트가 함께 동작할 때 문제가 없는지 검증하는 테스트입니다.
단위 테스트가 함수, 메서드, 클래스와 같은 개별 부품의 동작을 확인한다면, 통합 테스트는 그 부품들이 서로 연결되었을 때 정상적으로 협력하는지 확인합니다.
정리하면, 통합 테스트의 핵심은 “각 모듈이 맞는가”가 아니라 “모듈 사이의 계약이 맞는가”를 확인하는 것입니다.
🔷 통합 테스트가 필요한 이유
개별 클래스나 모듈이 단독으로는 정상 동작하더라도, 실제 애플리케이션에서는 여러 계층이 함께 동작합니다.
예를 들어 사용자 조회 또는 회원가입 기능은 다음과 같은 구조로 동작할 수 있습니다.
| 계층 | 역할 |
| ↓ UserController | 클라이언트 요청을 받고 응답을 반환 |
| ↓ UserService | 비즈니스 로직 처리 |
| ↓ UserRepository | 데이터베이스 접근 |
| Database | 실제 데이터 저장 및 조회 |
단위 테스트에서는 각 계층을 따로 검증할 수 있습니다. 하지만 실제로 계층들이 연결되면 예상하지 못한 문제가 발생할 수 있습니다.
| 가능한 문제 | 설명 |
| 잘못된 DTO 전달 | Controller가 Service에 필요한 값과 다른 형식의 데이터를 전달하는 경우 |
| 잘못된 메서드 호출 | Service가 Repository의 메서드를 잘못 호출하거나 잘못된 파라미터를 전달하는 경우 |
| SQL 또는 ORM 매핑 오류 | Repository의 SQL, Entity 매핑, 컬럼명, 관계 설정이 잘못된 경우 |
| DB 제약조건 위반 | NOT NULL, UNIQUE, FOREIGN KEY 등의 제약조건으로 저장이 실패하는 경우 |
| 트랜잭션 처리 오류 | commit, rollback 처리가 기대와 다르게 동작하는 경우 |
| 설정 문제 | Bean 등록, 의존성 주입, 환경 설정이 잘못된 경우 |
| 직렬화 / 역직렬화 문제 | JSON 요청과 응답 객체 간 변환이 올바르게 되지 않는 경우 |
✔️ 예시: 회원가입 통합 테스트
회원가입 기능을 예로 들면, 통합 테스트에서는 다음 흐름이 실제로 정상 동작하는지 확인할 수 있습니다.
회원가입 API 요청
↓
UserController에서 요청 데이터 수신
↓
UserService에서 회원가입 비즈니스 로직 처리
↓
UserRepository에서 DB 저장
↓
Database에 사용자 정보 저장
↓
정상 응답 반환
| 검증 항목 | 설명 |
| 요청 데이터 전달 | Controller가 Service로 데이터를 올바르게 전달하는지 확인 |
| 비즈니스 로직 수행 | Service에서 중복 이메일 검사, 비밀번호 암호화 등이 정상 수행되는지 확인 |
| DB 저장 여부 | Repository를 통해 실제 DB 또는 테스트 DB에 데이터가 저장되는지 확인 |
| 응답 결과 | API 응답 상태 코드와 응답 본문이 기대와 일치하는지 확인 |
| 예외 처리 | 중복 이메일, 잘못된 입력값 등 오류 상황이 올바르게 처리되는지 확인 |
통합 테스트에서는 테스트 범위를 어디까지 포함할지 결정해야 합니다. 예를 들어 Service와 Repository만 연결해서 테스트할 수도 있고, Controller부터 Database까지 포함해 API 요청 흐름 전체를 테스트할 수도 있습니다.
| 테스트 범위 | 설명 |
| Service + Repository | 비즈니스 로직과 DB 접근이 올바르게 연결되는지 확인 |
| Controller + Service | 요청 데이터가 비즈니스 로직으로 올바르게 전달되는지 확인 |
| Controller + Service + Repository + DB | API 요청부터 DB 저장까지 전체 계층 연결 확인 |
통합 테스트는 여러 코드 단위가 실제로 연결되었을 때 정상적으로 동작하는지 확인하는 테스트입니다. 이를 통해 단위 테스트만으로는 발견하기 어려운 DTO 전달 오류, Repository 호출 오류, DB 매핑 오류, 트랜잭션 문제, 설정 오류 등을 확인할 수 있습니다.
4. 시스템 테스트
시스템 테스트는 완성된 시스템 전체가 요구사항대로 동작하는지 검증하는 테스트입니다.
단위 테스트와 통합 테스트가 코드 내부 구조나 모듈 간 연결을 중심으로 검증한다면, 시스템 테스트는 사용자에게 제공되는 완성된 제품의 관점에서 전체 기능이 정상적으로 동작하는지 확인합니다.
즉, 개발자가 작성한 개별 코드가 아니라 사용자가 실제로 시스템을 사용하는 흐름을 기준으로 테스트합니다.
| 목적 | 설명 |
| 전체 흐름 검증 | 사용자가 실제로 수행하는 업무 흐름이 정상적으로 동작하는지 확인 |
| 요구사항 충족 확인 | 기능 요구사항과 비기능 요구사항을 만족하는지 검증 |
| 릴리스 품질 확보 | 배포 전 제품 수준에서 주요 문제가 없는지 확인 |
| 사용자 관점 검증 | 개발 내부 구조가 아니라 실제 사용 경험 기준으로 검증 |
시스템 테스트는 완성된 시스템이 요구사항 명세에 맞게 동작하는지를 확인합니다. 여기에는 기능 요구사항뿐 아니라 성능, 보안, 호환성 같은 비기능 요구사항도 포함될 수 있습니다.
🔷 시스템 테스트가 필요한 이유
단위 테스트와 통합 테스트를 모두 통과했더라도, 실제 사용자가 시스템을 사용할 때 문제가 발생할 수 있습니다.
예를 들어 쇼핑몰 시스템에서는 다음과 같은 전체 흐름이 정상적으로 동작해야 합니다.
회원가입
↓
로그인
↓
상품 검색
↓
장바구니 담기
↓
결제
↓
주문 완료
각 기능이 개별적으로는 정상 동작하더라도, 전체 흐름에서 다음과 같은 문제가 발생할 수 있습니다.
| 가능한 문제 | 설명 |
| 로그인 상태 유지 문제 | 로그인 후 상품 검색이나 결제 단계에서 인증 정보가 유지되지 않는 경우 |
| 화면 간 데이터 전달 오류 | 장바구니에 담은 상품 정보가 결제 화면에 제대로 전달되지 않는 경우 |
| 결제 연동 오류 | 결제 모듈과 주문 시스템 간 연동이 정상적으로 처리되지 않는 경우 |
| 주문 상태 오류 | 결제 완료 후 주문 상태가 정상적으로 변경되지 않는 경우 |
| 사용자 화면 오류 | 버튼, 입력창, 안내 메시지 등이 요구사항과 다르게 동작하는 경우 |
이러한 문제는 시스템 전체를 사용자 흐름 기준으로 검증해야 발견할 수 있습니다.
🔷 시스템 테스트의 주요 방법
| 방법 | 설명 |
| 블랙박스 테스트 | 내부 코드 구조를 보지 않고 입력값과 결과를 중심으로 검증 |
| 기능 테스트 | 요구사항 명세에 정의된 기능이 정상적으로 동작하는지 검증 |
| E2E 테스트 | 사용자의 실제 업무 흐름을 처음부터 끝까지 검증 |
| 회귀 테스트 | 코드 변경 후 기존 기능이 깨지지 않았는지 확인 |
| 성능 테스트 | 응답 시간, 처리량, 동시 사용자 수 등을 확인 |
| 보안 테스트 | 인증, 인가, 취약점, 민감 정보 노출 여부를 확인 |
| 호환성 테스트 | 브라우저, OS, 기기별로 시스템이 정상 동작하는지 확인 |
| 장애 / 복구 테스트 | 장애 상황에서 시스템이 어떻게 동작하고 복구되는지 검증 |
✔️ 예시: 주문 기능 E2E 테스트
쇼핑몰의 주문 기능을 E2E 테스트로 검증한다면 다음과 같은 흐름을 확인할 수 있습니다.
사용자가 로그인한다.
↓
상품을 검색한다.
↓
상품 상세 페이지로 이동한다.
↓
상품을 장바구니에 담는다.
↓
결제를 진행한다.
↓
주문 완료 화면을 확인한다.
이 테스트에서는 단순히 결제 함수 하나만 확인하는 것이 아니라, 사용자가 실제로 주문을 완료하기까지의 전체 과정을 검증합니다.
검증 항목은 다음과 같습니다.
| 검증 항목 | 설명 |
| 로그인 성공 여부 | 올바른 계정으로 로그인되는지 확인 |
| 상품 검색 결과 | 검색어에 맞는 상품이 정상적으로 조회되는지 확인 |
| 장바구니 반영 | 선택한 상품이 장바구니에 정확히 담기는지 확인 |
| 결제 처리 | 결제 요청이 정상적으로 처리되는지 확인 |
| 주문 생성 | 결제 완료 후 주문 데이터가 생성되는지 확인 |
| 주문 완료 화면 | 사용자에게 주문 완료 메시지와 주문 정보가 표시되는지 확인 |
시스템 테스트가 제품 전체의 기능적·비기능적 품질을 검증하는 단계라면, 인수 테스트는 그 결과가 실제 비즈니스 요구와 사용자 기대를 만족하는지 최종 확인하는 단계입니다.
5. 시스템 통합 테스트
시스템 통합 테스트는 서로 다른 시스템 간의 연동이 정상적으로 동작하는지 검증하는 테스트입니다.
통합 테스트가 주로 하나의 애플리케이션 내부 구성요소 간 연결을 검증한다면, 시스템 통합 테스트는 독립적으로 배포되거나 운영되는 여러 시스템 간의 연동을 검증합니다.
전통적인 V모델에서는 시스템 통합 테스트가 통합 테스트의 범위 안에 포함되기도 합니다. 하지만 최근에는 마이크로서비스, 외부 API, 메시지 기반 아키텍처처럼 시스템 간 연동이 복잡해지면서 별도의 테스트 단계로 관리하는 경우가 많습니다.
🔷 시스템 통합 테스트가 중요한 환경
| 환경 | 설명 |
| 마이크로서비스 아키텍처 | 여러 서비스가 API 또는 메시지로 서로 연동되는 구조 |
| 외부 결제 API 연동 | 카드사, PG사, 간편결제 서비스와의 결제 승인 및 취소 연동 |
| 본인인증 API 연동 | 휴대폰 인증, 공동인증서, 신분증 인증 등 외부 인증 기관 연동 |
| ERP, CRM, 레거시 시스템 연동 | 기존 업무 시스템과 신규 시스템 간 데이터 연계 |
| Kafka, RabbitMQ 기반 메시지 연동 | 이벤트 발행, 구독, 재처리, 중복 처리 등을 검증해야 하는 구조 |
이러한 환경에서는 한 시스템이 정상 동작하더라도, 다른 시스템과 연결되는 과정에서 데이터 형식, 응답 지연, 장애 처리, 상태 불일치 문제가 발생할 수 있습니다.
🔷 시스템 통합 테스트에서 확인해야 할 항목
| 확인 항목 | 설명 |
| 상태 변경 검증 | 결제 승인 후 주문 상태가 결제완료로 변경되는지 확인 |
| 데이터 포맷 검증 | 배송 시스템으로 전달되는 주소, 전화번호, 우편번호 형식이 맞는지 확인 |
| 데이터 정합성 검증 | 주문 금액과 결제 금액이 일치하는지 확인 |
| 이벤트 중복 처리 검증 | 동일한 메시지 이벤트가 중복 수신되어도 주문이나 결제가 중복 처리되지 않는지 확인 |
| 장애 처리 검증 | 외부 API timeout, 네트워크 오류, 응답 지연 발생 시 재시도 정책이 동작하는지 확인 |
| 트랜잭션 보상 처리 | 결제는 성공했지만 주문 저장이 실패한 경우 취소 또는 보상 처리가 수행되는지 확인 |
| 연동 순서 검증 | 주문 생성, 결제 승인, 배송 요청, 알림 발송이 올바른 순서로 처리되는지 확인 |
| 인증 및 권한 검증 | 외부 API 호출 시 필요한 인증키, 토큰, 권한 설정이 정상인지 확인 |
✔️ 예시: 주문-결제 연동 테스트
주문 시스템과 결제 시스템을 연동 테스트한다고 가정하면 다음 흐름을 확인할 수 있습니다.
사용자가 주문을 생성한다.
↓
주문 시스템이 결제 시스템에 결제 승인을 요청한다.
↓
결제 시스템이 승인 결과를 반환한다.
↓
주문 시스템이 주문 상태를 결제완료로 변경한다.
↓
결제 금액과 주문 금액이 일치하는지 확인한다.
테스트에서 검증할 수 있는 항목은 다음과 같습니다.
| 검증 항목 | 설명 |
| 결제 요청 데이터 | 주문번호, 결제금액, 사용자 정보가 결제 시스템에 올바르게 전달되는지 확인 |
| 결제 응답 처리 | 결제 승인 성공, 실패, 취소 응답을 주문 시스템이 올바르게 처리하는지 확인 |
| 주문 상태 변경 | 결제 성공 시 주문 상태가 정상적으로 변경되는지 확인 |
| 금액 정합성 | 주문 금액과 결제 승인 금액이 일치하는지 확인 |
| 실패 처리 | 결제 실패 시 주문 상태가 실패 또는 결제대기 상태로 처리되는지 확인 |
| 재시도 정책 | timeout 또는 일시적 장애 발생 시 재시도가 수행되는지 확인 |
🔷 대표적인 수행 방법
| 방법 | 설명 |
| 외부 API 테스트 | 외부 서비스의 요청 / 응답 형식, 상태 코드, 오류 응답 처리를 검증 |
| Sandbox 테스트 | 외부 기관 또는 업체가 제공하는 테스트 환경에서 실제 연동과 유사하게 검증 |
| 메시지 기반 테스트 | Kafka, RabbitMQ 등에서 이벤트 발행, 구독, 재처리, 중복 처리를 검증 |
| 데이터 정합성 테스트 | 시스템 간 주문번호, 금액, 상태값, 사용자 정보 등이 일치하는지 확인 |
| 장애 연계 테스트 | 외부 시스템 장애, timeout, 응답 지연, 네트워크 오류, 재시도 정책을 검증 |
| End-to-End 연계 테스트 | 여러 시스템을 거치는 전체 업무 흐름이 정상적으로 완료되는지 검증 |
시스템 통합 테스트는 여러 시스템이 API, 메시지, 파일, 배치 등으로 연결될 때 데이터 정합성, 상태 전이, 장애 처리, 재시도, 보상 처리까지 포함해 업무 흐름이 정상적으로 이어지는지 검증하는 테스트입니다.
6. 인수 테스트
인수 테스트는 사용자 또는 고객 관점에서 시스템을 받아들일 수 있는지 확인하는 테스트입니다.
즉, 단순히 “기능이 기술적으로 동작하는가?”를 확인하는 것이 아니라, “비즈니스 요구사항을 만족하고 실제 업무에 사용할 수 있는 수준인가?”를 검증합니다.
🔷 인수 테스트의 목적
인수 테스트의 핵심 목적은 다음 질문에 답하는 것입니다.
“이 기능은 요구사항을 충족했으며, 사용자에게 제공해도 되는가?”
예를 들어 다음과 같은 요구사항이 있다고 가정합니다.
사용자는 비밀번호가 8자 이상일 때만 회원가입을 진행할 수 있다.
이 요구사항은 개발자 관점에서는 비밀번호 검증 로직으로 볼 수 있습니다. 하지만 인수 테스트에서는 사용자 행동과 결과를 기준으로 표현해야 합니다.
개발자 관점의 표현은 다음과 같습니다.
validatePassword() 함수가 8자 이상이면 true를 반환한다.
반면 인수 테스트 관점의 표현은 다음과 같습니다.
사용자가 8자 이상의 비밀번호를 입력하면 회원가입을 진행할 수 있다.
사용자가 8자 미만의 비밀번호를 입력하면 회원가입을 진행할 수 없다.
인수 테스트에서는 내부 구현 방식보다 사용자 행동, 업무 조건, 기대 결과가 중요합니다.
✔️ 예시: 회원가입 비밀번호 검증
인수 테스트는 보통 사용자 시나리오 형태로 작성할 수 있습니다.
Feature: 회원가입 비밀번호 검증
Scenario: 사용자가 유효한 비밀번호를 입력한다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 이상의 비밀번호를 입력하면
Then 회원가입을 진행할 수 있다
Scenario: 사용자가 8자 미만의 비밀번호를 입력한다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 미만의 비밀번호를 입력하면
Then 회원가입을 진행할 수 없다
And 비밀번호는 8자 이상이어야 한다는 메시지를 보여준다
위 예시는 내부 구현 방식이 아니라 사용자가 어떤 상황에서 어떤 행동을 하고, 어떤 결과를 기대하는지를 기준으로 작성되어 있습니다.
🔷 대표적인 수행 방법
| 방법 | 설명 |
| UAT | 실제 사용자 또는 현업 담당자가 업무 관점에서 시스템을 검증 |
| 시나리오 테스트 | 사용자의 실제 업무 흐름을 기준으로 기능을 검증 |
| 인수 기준 테스트 | 사전에 정의한 Acceptance Criteria를 충족하는지 확인 |
| 알파 테스트 | 내부 조직 또는 제한된 사용자 그룹이 사전 검증 |
| 베타 테스트 | 외부 사용자 일부에게 배포하여 실제 사용 환경에서 검증 |
| 운영 리허설 | 배포, 데이터 이관, 롤백, 장애 대응 등 운영 절차까지 검증 |
인수 테스트에서는 구현 세부사항보다 사용자 행동과 비즈니스 결과를 표현하는 것이 중요합니다.
따라서 HTML 요소명, DB 컬럼명, 내부 상태값처럼 개발 내부 구조에 가까운 표현은 피하는 것이 좋습니다.
✔️ 예시: 인수 기준 작성 방식
회원가입 기능의 인수 기준은 다음과 같이 정리할 수 있습니다.
| 인수 기준 | 설명 |
| 비밀번호가 8자 이상이면 회원가입을 진행할 수 있다 | 유효한 비밀번호 입력 시 다음 단계로 진행 가능 |
| 비밀번호가 8자 미만이면 회원가입을 진행할 수 없다 | 잘못된 비밀번호 입력 시 가입 차단 |
| 오류 메시지를 제공한다 | 사용자가 문제를 이해할 수 있도록 안내 메시지 표시 |
| 사용자는 입력값을 수정할 수 있다 | 오류 발생 후 비밀번호를 다시 입력할 수 있어야 함 |
이를 시나리오 형태로 표현하면 다음과 같습니다.
Feature: 회원가입
Scenario: 비밀번호가 조건을 만족하면 회원가입을 진행할 수 있다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 이상의 비밀번호를 입력한다
Then 사용자는 회원가입을 진행할 수 있다
Scenario: 비밀번호가 조건을 만족하지 않으면 회원가입을 진행할 수 없다
Given 사용자가 회원가입 페이지에 있다
When 사용자가 8자 미만의 비밀번호를 입력한다
Then 사용자는 회원가입을 진행할 수 없다
And "비밀번호는 8자 이상이어야 합니다"라는 안내 메시지를 확인할 수 있다
인수 테스트는 기능이 고객과 사용자의 요구사항을 만족하는지 확인하는 테스트입니다. 시스템 테스트가 완성된 제품의 기능적·비기능적 품질을 확인한다면, 인수 테스트는 그 제품이 실제 업무와 사용자 기대를 충족하는지 최종적으로 판단합니다.
※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.
'5. IT기술노트 > 인프라&개발' 카테고리의 다른 글
| Redis의 기술적 특징과 고성능 데이터 처리 구조 (0) | 2026.05.27 |
|---|---|
| 행위 주도 개발 BDD(Behavior-Driven Development) 이해하기 (0) | 2026.05.07 |
| Latency Numbers로 설계하는 백엔드 아키텍처 (0) | 2026.05.05 |
| 테스트 주도 개발 TDD(Test-Driven Development) 이해하기 (0) | 2026.05.05 |
| CQRS 개념과 Read-Your-Own-Writes 해결 전략 (0) | 2026.02.09 |