Invisible Safety,

Proven by Intelligence

보이지 않는 안전을 인텔리전스로 증명하다.

기술 노트
IT 산업의 변화를 이끄는 MDS인텔리전스의
기술 인사이트를 만나보세요.
시스템 소프트웨어 개발
[VectorCAST] 단위시험에서 Stub은 왜 필요한가?
2026년 10월 06일

이번 포스팅에서는 VectorCAST로 단위시험을 구성할 때 마주하게 되는 stub에 대해 이야기해 보려 합니다. stub이 무엇인지, 왜 필요한지 살펴보도록 하겠습니다.



VectorCAST로 단위 시험 환경을 구성하고, 사용하다 보면 이런 상황을 어렵지 않게 마주치게 됩니다.

✔️외부 함수로 인해 빌드가 안되는 경우

✔️개발 중인 다른 모듈, 함수가 완성되지 않은 경우

✔️특정 오류 상황을 재현해야 하는데, 실제로 오류를 내기 어려운 경우



위의 경우들의 공통점은 바로 시험하고 싶은 함수가 하드웨어나 외부에 있는 다른 함수 등에 의존하고 있다는 점입니다. 



임베디드 개발 환경을 예로 들어 보겠습니다.



속도를 계산하는 calculate_speed() 함수를 시험한다고 할 때, 이 함수는 내부에서 다음과 같은 외부 함수를 호출합니다.


     read_adc_value()

     get_gear_ratio()

     get_system_tick()



그러나 단위 시험을 진행하려고 했더니 아직 준비되지 않는 부분들이 있습니다.



①    ADC 드라이버는 아직 개발 중입니다.

②    기어비 계산 함수는 다른 팀에서 개발 중입니다.

③    System Tick은 실제 하드웨어에서만 동작합니다.



결국 calculate_speed() 하나만 시험하고 싶었는데도 빌드가 되지 않거나, 외부 함수의 의존성으로 인해 시험이 어려운 경우가 있습니다. 이런 문제를 해결하기 위해 사용하는 것이 바로 stub입니다.





 Stub이란?


Stub은 시험 대상 함수(UUT)가 호출하는 외부 함수를 대신하는 임시 함수입니다.



실제 기능을 모두 구현하는 것이 아니라, 시험에 필요한 최소한의 동작만 수행합니다.



예를 들어, 다음과 같은 실제 함수가 있을 때,



uint16_t read_adc_value(uint8_t channel);



이 실제 함수 대신 아래의 함수를 호출합니다.



uint16_t read_adc_value(uint8_t channel)

{

    return 2048;

}



원하는 값을 반환하도록 만들어 UUT를 외부 의존성과 분리하는 것이 stub입니다.



즉,

"외부 환경은 잠시 잊고, 시험 대상 함수만 검증하자."

이것이 stub의 가장 중요한 목적입니다.





Stub은 언제 필요할까?


 ① 외부 구성 요소의 의존성 제거



임베디드 소프트웨어는 GPIO, UART, CAN, ADC와 같은 드라이버뿐 아니라 다른 모듈이나 라이브러리, 외부 함수 등 다양한 외부 구성 요소와 연동하여 동작합니다.



단위 시험의 목적은 시험 대상 함수(UUT) 자체의 동작을 검증하는 것입니다. 하지만 UUT가 실제 드라이버나 다른 모듈을 그대로 호출하면, 외부 구성 요소의 동작까지 시험 결과에 영향을 줄 수 있습니다.



예를 들어 ADC 값을 읽는 함수가 항상 실제 ADC 드라이버를 호출한다면, ADC의 상태나 드라이버의 구현에 따라 시험 결과가 달라질 수 있습니다.



이때 stub을 사용하면 실제 드라이버 대신 원하는 값을 반환하도록 제어할 수 있어, 외부 구성 요소의 영향을 배제한 상태에서 UUT의 로직만 독립적으로 검증할 수 있습니다.




② 복잡한 호출 관계 단순화



시험 대상 함수에는 여러 단계의 함수를 연쇄적으로 호출하는 경우도 많습니다.



예를 들어 calculate_speed() 함수가 내부적으로 read_abc_value(), read_can_message(), check_sensor() 등을 차례로 호출한다면, 단순히 calculate_speed()의 로직을 검증하고 싶어도 하위 함수들의 동작까지 모두 확인해야 합니다.



이처럼 함수 호출 구조가 깊어질수록 시험 환경 구성은 복잡해지고, 경우에 따라서는 시험 대상 함수보다 호출되는 함수의 동작을 이해하는 데 더 많은 시간을 소요하기도 합니다.



Stub을 활용하면 하위 함수를 시험 목적에 맞게 단순화할 수 있으므로, 시험 범위를 UUT에 집중할 수 있고 불필요한 의존성을 줄일 수 있습니다.




③ 시험 조건 제어 및 다양한 시나리오 검증



단위 시험은 같은 조건에서 언제 실행하더라도 동일한 결과를 얻을 수 있어야 합니다. 또한 정상 동작뿐 아니라 경계 조건과 오류 상황까지 검증할 수 있어야 합니다.



하지만 실제 함수는 센서 값, 시스템 시간, 통신 상태 등 외부 환경에 따라 반환 값이 계속 달라질 수 있습니다. 이런 경우에는 동일한 시험을 반복하거나 특정 오류 상황을 재현하기가 쉽지 않습니다.



Stub을 사용하면 시험 목적에 맞게 반환 값을 자유롭게 제어할 수 있습니다.



✅정상 값을 반환하여 일반 동작을 검증

✅경계 값을 반환하여 예외 처리 확인

✅오류 값을 반환하여 오류 대응 로직 검증

✅Timeout, 통신 오류 등 실제 환경에서 재현하기 어려운 상황 구성



예를 들어 CAN 통신 함수를 stub으로 대체하면, Timeout이나 통신 오류를 반복적으로 재현하여 예외 처리 로직을 검증할 수 있습니다.



이처럼 Stub은 반복 가능한 시험 환경을 구성하는 동시에 다양한 시험 시나리오를 손쉽게 구현할 수 있도록 지원합니다.





VectorCAST에서는 어떻게 지원할까?



VectorCAST는 stub 생성을 자동으로 지원합니다.



환경을 생성하면 시험 대상 함수가 호출하는 외부 함수를 기반으로 Stub을 자동 생성하며, 테스트 케이스에서 반환 값과 입력 값 등을 손쉽게 설정할 수 있습니다. 





그림과 같이 VectorCAST에서 calculate_speed라는 함수를 시험할 때, TestCase를 작성하는 화면입니다. 함수 내부에서 호출하는 외부 함수들이 자동으로 stub 처리되어 있어, calculate_speed에 대한 단위 시험을 수월하게 진행할 수 있습니다.



이처럼 VectorCAST는 시험 대상 함수와 연관된 외부함수를 분석하여 함수의 인자, 반환 값, 내부에서 사용하는 전역변수 등 함수에서 필요한 변수와 타입을 모두 설정할 수 있는 stub을 자동으로 생성하고 테스트할 수 있도록 지원합니다.





마무리하며... 



단위 시험의 목적은 단순히 코드가 정상적으로 동작하는지 확인하는 것이 아닙니다.



다양한 조건에서도 예상한 대로 동작하는지 검증하는 것이 더 중요합니다.



Stub은 이러한 시험 환경을 만드는 핵심 요소이며, 외부 구성요소와의 의존성 제거, 반복 가능한 시험 환경 구성, 오류 상황 재현 등 다양한 역할을 수행합니다.



이번 글에서는 Stub의 개념과 필요성을 살펴봤습니다.



실제 프로젝트에서는 Stub 설정뿐 아니라 Environment 구성, Test Case 작성, Coverage 분석까지 함께 이해해야 효율적으로 단위 시험을 수행할 수 있습니다.



VectorCAST는 이러한 과정을 자동화하여 수월한 단위시험을 진행할 수 있도록 지원합니다.

 




📧 vectorcast@mdsit.co.kr ✍️문의남기기