SW Engineering & Testing (12) - Integration Testing

Charlie·2026년 5월 26일

SE&Testing

목록 보기
13/13

Introduction

IEEE 표준 결함 유형과 통합 테스팅의 타겟

IEEE Standard Classification(1993)에 따르면 소프트웨어 결함은 여러 가지로 분류되는데, 테스트 단계별로 타겟팅하는 결함이 다르다.

1. 단위 테스팅(Unit Testing)의 타겟

주로 화이트박스 및 데이터 흐름 테스팅을 통해 내부 로직 결함(Logic Faults), 계산 결함(Computation Faults), 데이터 결함(Data Faults) 등을 잡아냅니다.

2. 통합 테스팅(Integration Testing)의 타겟

모듈들이 결합될 때 발생하는 '인터페이스 결함(Interface Faults)'을 찾아내는 데 집중한다.

인터페이스 결함의 구체적 종류

  • 타이밍 오류 (I/O timing)
  • 잘못된 프로시저 호출 (Call to wrong procedure)
  • 존재하지 않는 프로시저 호출 (Call to nonexistent procedure)
  • 파라미터 불일치 (Parameter mismatch (type, number))
  • 호환되지 않는 타입 (Incompatible types).

Interface testing

Interface testing의 목적은 모듈 간 인터페이스의 직접적인 오류나, 인터페이스에 대한 잘못된 가정(Invalid assumptions)으로 인해 발생하는 결함을 감지하는 것이다.

1) Interface misuse (인터페이스 오용 / 잘못된 사용)

호출하는 컴포넌트(Calling component)가 다른 컴포넌트를 호출할 때 인터페이스 사용에 물리적/구문적 실수를 하는 경우를 말한다.

주로 시스템이 정해둔 규칙을 개발자가 코딩 과정에서 단순하게 틀리게 작성한 경우를 말한다. 가장 흔한 예시로 파라미터(매개변수)의 순서를 뒤바꿔서 전달하거나, 정수(int)를 넣어야 할 자리에 문자열(string)을 넣는 등의 실수가 여기에 해당한다.

2) Interface misunderstanding (인터페이스 오해 / 잘못된 이해)

호출하는 컴포넌트가 호출받는 컴포넌트의 동작 방식에 대해 부정확하고 잘못된 가정(Assumptions)을 내포하고 있는 경우를 말한다.

파라미터의 타입이나 순서는 맞아서 프로그램 자체는 에러 없이 돌아가지만, 그 안의 '의미(논리)'를 서로 다르게 해석하여 발생하는 문제를 생각해볼 수 있다.

대표적인 사례로 NASA의 화성 기후 궤도선 폭발 사고(Mars Climate Orbiter Accident)가 있다. 이 사고는 록히드 마틴은 '파운드' 단위로 데이터를 넘겼는데, NASA는 이를 '미터법(뉴턴)' 단위일 것이라고 '잘못된 가정'을 한 채로 모듈을 결합했다가 우주선이 폭발해버린 사례이다.

3) Timing errors (타이밍 오류)

호출하는 컴포넌트와 호출받는 컴포넌트의 작동 속도(Speed)가 달라서, 오래된(Out-of-date) 정보에 접근하게 되는 문제를 말한다.

두 개 이상의 모듈이 동시에 실행되는 환경(특히 실시간 시스템이나 병렬 처리 시스템)에서 주로 발생한다. 예를 들어, 모듈 A가 새로운 센서 값을 아직 데이터베이스에 업데이트(저장)하지도 않았는데, 모듈 B가 한발 앞서서 데이터베이스를 읽어버려 과거의 낡은 값을 바탕으로 잘못된 제어 명령을 내리는 동기화 문제가 이에 해당한다.

4) 사례 : 화성 기후 궤도선 사고 (Mars Climate Orbiter Accident)

1998년 12월에 발사된 338kg의 로봇 우주 탐사선이 41주 동안 4억 1,600만 마일을 날아간 후 1999년 9월에 완전히 실종(파괴)되었다.

사고 원인 (의사소통 및 인터페이스 오류)

스템을 공동 개발한 NASA와 록히드 마틴(Lockheed) 간의 의사소통 오해 때문에 발생했으며, 한쪽(록히드 마틴)은 파운드(Pound Unit) 단위를 사용하여 추력 데이터를 계산해 넘겼고 다른 한쪽(NASA)은 이를 뉴턴(Newton Metric Unit) 미터법 단위로 착각하여 받아들였다.

즉, 개별 모듈(단위)은 완벽하게 작동했을지라도, 모듈 간 데이터를 주고받는 인터페이스 단계에서 단위(Type)에 대한 잘못된 가정을 테스트로 걸러내지 못해 막대한 비용이 투입된 우주선이 폭발해버린 통합 결함의 대표적 사례이다.

Integration Testing(통합 테스팅)

개별 모듈들이 결합되었을 때 모듈 간의 상호작용(Interactions among modules)이 올바르게 일어나는지에 초점을 맞춘다. 통합 테스팅은 명세서(Specification)를 바탕으로 테스트 케이스를 도출하는 블랙박스 테스팅(Black-box testing)으로 수행되어야 한다.

결함이 발생했을 때 오류의 정확한 위치를 파악(Localising errors)하는 것이 어려움으로 작용하고 이를 해결하는 방법으로는 점진적 통합 테스팅(Incremental integration testing) 이 존재한다. 이는 모든 모듈을 한 번에 결합하지 않고 점진적으로 추가하는 방식이다.

통합 테스팅은 아래의 네가지 접근법을 가진다.

1. Big Bang (빅뱅 통합)
2. Decomposition-based integration (분해 기반 통합)
3. Call Graph-based integration (호출 그래프 기반 통합)
4. Path-based integration (경로 기반 통합)

점진적 통합 테스팅 (Incremental Integration Testing)

한 번에 모듈을 다 합치는 것이 아니라 단계별로 묶어서(Sequence) 테스트하는 방식으로, 자료의 다이어그램(A, B, C, D 모듈 결합)을 통해 이를 명확히 보여준다.

총 3가지의 Test Sequence로 나눠서 테스트를 수행하는 것을 예시로 설명하자면,
Test Sequence 1
모듈 A와 B를 결합하여 먼저 테스트(T1, T2, T3)를 수행한다.
Test Sequence 2
앞서 결합된 A, B 시스템에 모듈 C를 추가 결합하여 테스트(T1, T2, T3, T4)를 수행한다.
Test Sequence 3
마지막으로 모듈 D까지 전부 결합하여 테스트(T1, T2, T3, T4, T5)를 수행한다.

결과적으로 오류가 나더라도 새로 추가된 모듈과의 연결 부위를 의심하면 되므로 디버깅이 매우 쉬워지는 효과를 얻을 수 있다.

분해 기반 통합 (Decomposition-based Integration)

시스템을 기능적으로 분해한 구조(트리 형태)를 바탕으로 결합하는 방식이며, 방향에 따라 3가지로 나뉜다.

1) Top-down testing (하향식 테스팅)

최상위(High-level) 시스템부터 시작하여 위에서 아래로(Top-down) 점진적으로 통합하는 방식을 말하고, 아직 개발되지 않은 하위 컴포넌트의 자리는 임시 가짜 모듈인 '스텁(Stubs)'으로 교체(replacing)하여 테스트하는 방식을 말한다.

Level 1을 먼저 테스트하고, 하위 계층은 Level 2 stubs, Level 3 stubs로 대체하여 진행하는 것이다.

2) Bottom-up testing (상향식 테스팅)

최하위의 개별 컴포넌트부터 시작하여 아래에서 위로(Bottom-up) 점진적으로 결합해 완전한 시스템을 만든다. 하위 모듈을 호출해 줄 상위 모듈이 아직 없으므로, 이를 대신해 하위 모듈에 명령을 내리는 '테스트 드라이버(Test drivers)'가 필요하다.

Level N, Level N-1 모듈들을 최상단의 Test drivers가 제어하며 테스트한다.

3) Sandwich integration (샌드위치 통합)

하향식(Top-down)과 상향식(Bottom-up) 통합 방식을 혼합(Combination)한 방식이다.

실습: Calendar Program Example (기능 분해 구조)

달력 프로그램의 통합 테스팅 실습을 위해 시스템을 다음과 같은 기능 트리(Functional decomposition)로 분해한다. 최상위 루트는 Calendar (Main) 이고, 하위 서브 모듈들은 아래의 리스트와 같다.

하위 서브 모듈들:

  • isLeap: 윤년 판별
  • weekDay: 해당 날짜의 요일 계산 (Mon, Tue 등)
  • getDate: 날짜 정보 가져오기 (하위에 isValidDate \rightarrow lastDayOfMonth \rightarrow dateToDaynumgetDigits를 가짐)
  • Zodiac: 해당 날짜의 별자리 기호(Zodiac sign) 판별
  • nextDate: 다음 날짜(NextDate) 계산
  • Friday13th: 가장 최근의 13일의 금요일 찾기
  • Memorial day: 5월 27일에 기념일이 열린 가장 최근 연도 찾기

Calendar Program을 통한 3가지 통합 테스팅 적용

앞서 나눈 달력 프로그램 구조를 하향식, 상향식, 샌드위치 방식으로 어떻게 테스트하는지 구체적으로 보여준다.

① Top-down (하향식)

최상단의 Calendar (Main) 모듈을 테스트하기 위해 하위 모듈인 zodiac 함수가 아직 완성되지 않았다고 가정한다.

이때 하위 모듈을 대체할 Test Stub(테스트 스텁) 을 작성하는데, 자료에서는 구체적으로 다음과 같은 C언어 스타일의 스텁 코드를 예시로 보여준다.

② Bottom-up (상향식)

최하위 모듈인 zodiac을 테스트하기 위해, 이를 호출해 줄 Test driver(테스트 드라이버)Calendar (driver)를 임시로 만든다.

여기서 핵심 포인트는 "Test drivers are more complex than test stubs (테스트 드라이버가 스텁보다 만들기 훨씬 복잡하다)" 는 점이다.

예를 들어, 별자리(zodiac)를 완벽히 테스트하려면 드라이버에서 총 36개의 테스트 케이스(Call zodiac : 36 TC (before, 0, after)) 를 일일이 세팅하고 호출해 주어야 한다.

③ Sandwich (샌드위치)

이 방식은 서브 트리(sub-tree) 단위로 빅뱅 통합(Doing big bang integration) 을 수행하는 것과 유사하다. 드라이버나 스텁 없이, 트리의 루트(root)부터 리프(leaves)까지 이어지는 전체 경로(A full path)를 한 번에 묶어서 테스트한다.

모듈을 크게 묶어버렸기 때문에 오류가 발생했을 때 어느 모듈에서 문제가 생겼는지 격리하기가 매우 어렵다(It is difficult to isolate faults)는 치명적인 단점이 있다.

호출 그래프 기반 통합 (Call Graph-based integration)

앞서 전반부에서 다룬 분해 기반(하향식, 상향식, 샌드위치) 통합 테스팅에 이어, 모듈 간의 호출 관계도(Call Graph)를 바탕으로 통합 테스팅을 진행하는 4가지 접근법 중 하나이다.

System Testing

1. 시나리오 기반 테스팅 (Scenario-based Testing)

시스템 테스팅은 전체 시스템의 실제 요구사항이 잘 동작하는지 확인하는 단계로, '시나리오 기반 테스팅'이 주로 활용된다.

1) 유스케이스 다이어그램 (Use Case Diagram)

사용자의 요구사항을 식별하여 Use Case Diagram을 작성한다.

예시로 나온 '유명 미술품 딜러(오스버트)를 위한 관리 시스템'에서는 오스버트, 판매자(Seller), 구매자(Buyer)라는 액터가 등장하며, '그림 구매', '그림 판매', '보고서 생성' 등의 유스케이스를 도출한다.

2) 유스케이스 명세 및 시나리오

'명작 구매(Buy a Masterpiece)' 시나리오를 보면, 설명 입력 → 경매 기록 스캔 → 유사 작품의 과거 낙찰가 기준 연 8.5% 복리를 가산하여 최대 구매가 산정 → 판매자 정보 입력과 같은 구체적인 흐름을 정의한다.

3) 시퀀스 다이어그램 (Sequence Diagram)

해당 유스케이스가 내부적으로 어떻게 동작하는지 명세한다.

판매자와 오스버트 사이에서 UI 클래스, 가격 계산 클래스, 경매 기록 데이터 클래스 등이 어떤 순서로 메시지(예: 가격 계산, 데이터 전송 등)를 주고받는지 시간의 흐름에 따라 나타낸다.

2. GUI 테스팅 (GUI Testing)

현대 애플리케이션의 핵심인 그래픽 사용자 인터페이스(GUI)를 테스트하는 것은 매우 중요하면서도 까다로운 작업이다.

1) GUI(웹) 애플리케이션의 3계층 구조

총 3개의 계층으로 구성되고, 각각 프레젠테이션 계층, 애플리케이션 계층, 데이터 계층으로 나뉜다.

  • 프레젠테이션 계층 (Front-end): HTML5, JavaScript, CSS로 구성되며, 사용자에게 직접 보여지는 인터페이스를 관리한다.
  • 애플리케이션 계층 (Back-end): Java, .NET, Python 등으로 구현되며, 프론트엔드의 요청에 응답하여 실제 고객의 요청을 처리하는 비즈니스 로직을 담당한다.
  • 데이터 계층 (Data Layer): MySQL, Oracle 등 데이터베이스 및 파일 서버를 통해 안정적인 데이터 관리를 수행한다.
    .

2) GUI 테스팅의 본질적인 한계와 이슈

단순한 명령줄(CLI) 기반 시스템과 달리 조작 경우의 수가 기하급수적으로 많아진다. 예를 들어 마이크로소프트 워드패드 같은 소형 프로그램조차 325개의 GUI 조작 경우의 수가 존재한다.

특정 기능을 수행하기 위해 이벤트의 연속성(Sequence of GUI events) 이 필요하다. 예를 들어 파일을 열려면 '파일 메뉴 클릭 → 열기 선택 → 대화상자에 파일명 입력 → 새 창으로 포커스 이동'이라는 일련의 과정을 거쳐야 하므로 순서 조합 문제가 폭발적으로 증가한다.

3) GUI 테스팅 수행 기법 4가지

어떻게 테스트 케이스를 만들고 이벤트를 입력하며 결과를 확인할 것인지에 따라 4가지로 나뉜다.

A. 수동 테스팅 (Manual Testing)

비즈니스 요구사항 문서에 명시된 내용에 따라 테스터가 직접 마우스와 키보드를 조작하여 화면이 맞게 동작하는지 확인한다.

B. 모델 기반 테스팅 (Model-based Testing)

시스템의 동작을 그래픽 모델로 변환하여 작동 방식을 예측한다.

시스템 요구사항을 바탕으로 효율적인 테스트 케이스를 생성하며, 특히 GUI가 절대 도달해서는 안 되는 '원치 않는 상태(undesirable state)'를 식별해 내는 데 장점을 가진다.

C. 레코드 및 리플레이 (Record & Replay)

도구가 사용자의 마우스 움직임, 키보드 입력 등의 모든 상호작용을 스크립트로 캡처(기록)해 두었다가, 정확히 동일한 상호작용 세션을 자동으로 재실행(Playback)하는 방식이다.

OS와 디바이스 드라이버 단의 이벤트를 낚아채어 작동한다.

D. 스크립팅 테스팅 (Scripting Testing)

프로그래밍 언어를 사용하여 테스트 스크립트를 작성한다.

실행 중 발생하는 인간의 실수를 원천적으로 제거할 수 있으며, 코드를 약간 수정하여 회귀 테스트(Regression Testing)에 지속적으로 재사용할 수 있다.


3. 주요 자동화 테스팅 도구

GUI 테스팅을 효율적으로 수행하기 위한 대표적인 자동화 도구들이다.

1. TestComplete

코딩 지식이 없는 팀도 사용하기 좋은 스크립트리스(Scriptless) 레코드 및 리플레이 도구다.

데스크톱, 모바일, 웹 환경을 모두 지원하며, AI 기반 객체 인식 엔진을 탑재하여 스마트한 테스트 보고서를 제공하는 것이 특징이다.

2. Selenium (셀레늄)

웹 애플리케이션 검증에 가장 널리 쓰이는 무료 오픈소스 프레임워크이다.

Java, Python, C# 등 다양한 프로그래밍 언어로 스크립트를 짤 수 있으며, WebDriver API를 사용하여 브라우저의 동작을 훨씬 더 현대적이고 안정적인 방식으로 자동 제어한다.

3. GUITAR

네이버(Naver)에서 제공하는 GUI 기반의 테스트 자동화 프레임워크이며, 사용자의 작업 정보로 생성된 테스트 스크립트를 직접 또는 원격으로 실행(Agent 활용)하여 반복적인 테스트를 수행한다.

테스트 시나리오를 한국어로 작성할 수 있다는 편의성이 있고, 로그인과 같이 여러 ID와 비밀번호 입력이 반복적으로 요구되는 시나리오를 효과적으로 자동화할 수 있다.

4. Apache Maven (마븐)

Java 프로젝트의 빌드(Build) 및 외부 라이브러리 의존성(Dependency)을 관리하는 핵심 도구이다.

프로젝트의 구조와 라이브러리를 표준화하여 관리하며, 설정에는 XML 기반의 pom.xml 파일을 사용한다.

5. 그 외

크로스 플랫폼 테스팅을 위한 OpenText Functional Testing (VBScript 사용)과 IBM DevOps Test UI 등이 존재한다.

4. CI/CD 기반 UI 테스트 자동화 (Selenium + JUnit + Maven)

코드 작성 \rightarrow 빌드 \rightarrow 테스트 \rightarrow 배포로 이어지는 전체 과정을 자동화하는 CI/CD (Continuous Integration/Continuous Delivery) 연계 전략이다.

프론트엔드부터 백엔드까지 각 자동화 도구는 다음과 같이 역할을 분담하여 파이프라인을 구성한다.

  • Maven: 전체적인 의존성 관리, 빌드(Maven Build) 수행, 테스트 실행 과정을 통제한다.
  • JUnit: 자바 기반 테스트 프레임워크로서, JUnit Test 단계에서 Assert문을 활용해 결과의 성공/실패를 검증한다.
  • Selenium WebDriver: 웹 브라우저를 자동으로 제어하여 사용자의 동작을 모방하는 Selenium UI Test를 수행한다.

개발자가 코드를 커밋(Code Commit)하면 빌드와 단위 테스트, UI 테스트가 순차적으로 자동 실행되며, 이 결과를 바탕으로 최종 배포 여부를 결정하게 된다.

profile
찬찬히 써내려가는 개발일지

0개의 댓글