GoogleTest를 활용한 ESP-IDF 구성 요소 단위 테스트 (호스트 기반)

발행: (2026년 2월 22일 오후 03:05 GMT+9)
6 분 소요
원문: Dev.to

Source: Dev.to

번역할 텍스트가 제공되지 않았습니다. 번역을 원하시는 본문을 알려주시면 한국어로 번역해 드리겠습니다.

소개

보드를 매번 플래시하지 않고 ESP‑IDF 구성 요소 로직을 테스트할 방법이 필요했습니다.
ESP‑IDF는 Linux 타깃으로 빌드할 수 있어 테스트를 호스트 머신에서 직접 실행할 수 있습니다.
이 가이드는 테스트 프레임워크로 GoogleTest를 사용하여 설정하는 방법을 보여줍니다. 예제 저장소는 aluigiotomazelli/gtest‑esp‑idf (chapter 01_basic_test)입니다.

사전 요구 사항

  • ESP‑IDF 5.x 설치 및 환경 설정
  • Linux 머신 또는 WSL2
  • ESP‑IDF Linux 타겟에 필요한 시스템 패키지
sudo apt install libbsd0 libbsd-dev

If you use the official ESP‑IDF Docker container (idf-env:latest), the packages are already present.

Note: Ruby는 CMock‑기반 IDF 모크에만 필요하며, 이는 이후 장에서 다룹니다.

저장소 레이아웃

01_basic_test/
├── CMakeLists.txt
├── include/
│   ├── i_sum.hpp     # Interface (abstract base class)
│   └── sum.hpp       # Concrete class header
├── src/
│   └── sum.cpp       # Production code
├── host_test/
│   ├── gtest/        # GTest wrapper component (CMake only)
│   └── test_sum/    # Test project for the Sum class
└── test_apps/        # Hardware verification (not used for host tests)
  • **src/**와 **include/**는 프로덕션 코드를 포함합니다.
  • **host_test/**는 모든 호스트‑사이드 테스트 코드를 포함합니다; 두 디렉터리는 절대로 섞이지 않습니다.

i_sum.hpp

Sum에 대한 추상 베이스 클래스를 정의합니다. 이 간단한 예제에서는 반드시 필요하지 않지만, 나중에 GMock을 사용해 목(mock)을 만들 때 유용한 패턴을 보여줍니다.

GoogleTest를 컴포넌트로 추가하기

GoogleTest는 ESP‑IDF에 포함되어 있지 않으므로, host_test/gtest/에 위치한 래퍼 컴포넌트를 통해 도입합니다. 래퍼는 CMakeLists.txt 파일 하나만 포함합니다:

# host_test/gtest/CMakeLists.txt
if(IDF_TARGET STREQUAL "linux")
    include(FetchContent)

    FetchContent_Declare(
        googletest
        GIT_REPOSITORY https://github.com/google/googletest.git
        GIT_TAG        v1.14.0
    )

    # FetchContent must run during the real build phase, not the dependency‑scan phase
    if(NOT CMAKE_BUILD_EARLY_EXPANSION)
        FetchContent_MakeAvailable(googletest)
    endif()

    # Register as an INTERFACE library so other components can link to GTest/GMock
    add_library(gtest INTERFACE)
    target_link_libraries(gtest INTERFACE gtest gmock)
    target_include_directories(gtest INTERFACE
        ${googletest_SOURCE_DIR}/include
    )
endif()

핵심 포인트

  • Linux 전용 가드 – 빌드 대상이 linux일 때만 컴포넌트가 처리됩니다.
  • FetchContent – 빌드 시점에 GTest를 다운로드합니다; 버전을 업데이트하려면 GIT_TAG만 바꾸면 됩니다.
  • 빌드 단계 가드 – 초기 의존성 스캔 단계에서 다운로드 시도를 방지합니다.
  • INTERFACE 라이브러리 – 래퍼 자체는 아무 것도 컴파일하지 않으며, REQUIRES하는 프로젝트에 GTest/GMock을 노출하기만 합니다.

테스트 프로젝트 구성

테스트 프로젝트는 host_test/test_sum/에 있습니다. 중요한 CMake 설정:

# host_test/test_sum/CMakeLists.txt
cmake_minimum_required(VERSION 3.16)

set(EXTRA_COMPONENT_DIRS
    "${CMAKE_CURRENT_LIST_DIR}/../../.."   # 레포지토리 루트 (테스트 대상 컴포넌트가 포함된 위치)
    "${CMAKE_CURRENT_LIST_DIR}/../gtest"   # GTest 래퍼
)

idf_component_register(
    SRCS "test_sum.cpp"
    INCLUDE_DIRS "."
    REQUIRES sum gtest
    WHOLE_ARCHIVE   # 정적 생성자(GoogleTest 등록)가 제거되지 않도록 보장
)
  • EXTRA_COMPONENT_DIRS는 테스트 대상 컴포넌트(sum)와 GTest 래퍼를 가리키며, 두 경로는 테스트 프로젝트 폴더 밖에 있습니다.
  • REQUIRES는 필요한 컴포넌트만 나열하여 빌드 속도를 빠르게 유지합니다.
  • WHOLE_ARCHIVE는 모든 오브젝트 파일을 포함하도록 강제하여 GoogleTest가 테스트를 탐지할 수 있게 합니다.

예제 테스트 코드

// host_test/test_sum/test_sum.cpp
#include 
#include "sum.hpp"

TEST(TestSum, GTestSmokeTest) {
    EXPECT_TRUE(true);   // verifies that GoogleTest itself runs
}

TEST(TestSum, Add) {
    Sum s;
    EXPECT_EQ(s.add(2, 3), 5);
    EXPECT_EQ(s.add(-1, -4), -5);
    EXPECT_EQ(s.add(0, 0), 0);
}

TEST(TestSum, AddConstrained_InRange) {
    Sum s;
    EXPECT_EQ(s.add_constrained(3, 4), 7);   // 7 ≤ 10
}

TEST(TestSum, AddConstrained_AtLimit) {
    Sum s;
    EXPECT_EQ(s.add_constrained(5, 5), 10);  // exactly the limit
}

TEST(TestSum, AddConstrained_OutOfRange) {
    Sum s;
    EXPECT_EQ(s.add_constrained(6, 5), -1); // 11 > 10 → -1
}

호스트 테스트 빌드 및 실행

cd 01_basic_test/host_test/test_sum
idf.py --preview set-target linux   # Linux target is still experimental
idf.py build
./build/test_sum.elf

예상 출력

[==========] Running 6 tests from 1 test suite.
[----------] 6 tests from TestSum
[ RUN      ] TestSum.GTestSmokeTest
[       OK ] TestSum.GTestSmokeTest (0 ms)
...
[  PASSED  ] 6 tests.

Continuous Integration

레포지토리에는 공식 ESP‑IDF Docker 컨테이너를 사용하여 푸시마다 호스트 테스트를 실행하는 GitHub Actions 워크플로가 포함되어 있습니다. 하드웨어가 필요 없으므로 CI는 표준 GitHub 러너에서 실행됩니다.

다음은 무엇인가요?

  • GMock를 사용하여 모의 객체를 통해 구성 요소를 격리합니다.
  • CMock‑based 접근 방식(ESP‑IDF 내부에서 사용)으로 하드웨어 의존성을 모킹합니다.

전체 소스 코드는 **github.com/aluiziotomazelli/gtest-esp-idf**에서 확인할 수 있습니다.

0 조회
Back to Blog

관련 글

더 보기 »

TCP/IP 및 데이터 흐름 소개

1. Data Flow 데이터 흐름은 컴퓨터 네트워크에서 데이터 패킷이 장치 간에 구조화된 이동, 관리 및 변환을 의미하며, 효율성을 보장합니다.