모던 CMake를 활용하여 효율적인 C++ 프로젝트 빌드 시스템을 구축하는 방법을 계속해서 알아보겠습니다. 이번 글에서는 CMake를 활용한 테스트 설정과 CI/CD 파이프라인에 연동하는 방법에 대해 다루겠습니다.
CMake와 테스트 프레임워크
소프트웨어 품질을 높이기 위해서는 단위 테스트(Unit Test)가 필수적입니다. CMake는 테스트를 지원하기 위한 모듈과 명령어를 제공하며, 다양한 테스트 프레임워크와 쉽게 연동할 수 있습니다.
CTest 소개
CTest는 CMake에 내장된 테스트 러너로, 테스트를 실행하고 결과를 보고하는 기능을 제공합니다.
- enable_testing(): 테스트를 활성화합니다.
- add_test(): 테스트를 등록합니다.
Google Test와 CMake 연동
Google Test는 C++에서 널리 사용되는 단위 테스트 프레임워크입니다. FetchContent를 사용하여 프로젝트에 포함하고 CMake로 빌드할 수 있습니다.
FetchContent를 사용한 Google Test 포함
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/release-1.11.0.zip
)
# 빌드 옵션 설정 (옵션)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
테스트 타겟 추가
enable_testing()
add_executable(MyTests tests/test.cpp)
target_link_libraries(MyTests PRIVATE MyLib gtest_main)
add_test(NAME MyTest COMMAND MyTests)
- enable_testing(): 테스트 기능을 활성화합니다.
- add_executable(MyTests tests/test.cpp): 테스트 실행 파일을 생성합니다.
- target_link_libraries(MyTests PRIVATE MyLib gtest_main): 테스트 타겟에 라이브러리와 Google Test를 링크합니다.
- add_test(): 테스트를 등록하여 ctest로 실행할 수 있게 합니다.
예제 디렉토리 구조
my_project/
├── CMakeLists.txt
├── src/
│ ├── CMakeLists.txt
│ └── mylib.cpp
├── include/
│ └── mylib.h
└── tests/
├── CMakeLists.txt
└── test.cpp
최상위 CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject)
add_subdirectory(src)
add_subdirectory(tests)
tests/CMakeLists.txt
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/release-1.11.0.zip
)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(MyTests test.cpp)
target_link_libraries(MyTests PRIVATE MyLib gtest_main)
add_test(NAME MyTest COMMAND MyTests)
테스트 실행
빌드 디렉토리에서 다음 명령어를 실행합니다.
cmake --build . --target MyTests
ctest
- ctest는 현재 디렉토리의 테스트를 모두 실행합니다.
코드 커버리지 측정
코드 커버리지는 테스트가 코드의 어느 부분을 실행하는지 분석하여 테스트의 효율성을 판단하는 데 도움이 됩니다.
GCC를 사용한 코드 커버리지 설정
컴파일러 플래그 추가
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(MyLib PRIVATE --coverage)
target_link_options(MyLib PRIVATE --coverage)
endif()
- --coverage 옵션을 추가하여 커버리지 데이터를 수집합니다.
커버리지 리포트 생성
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory coverage_report
- lcov와 genhtml을 사용하여 HTML 형태의 커버리지 리포트를 생성합니다.
CI/CD 파이프라인에 CMake 통합
CI/CD(Continuous Integration/Continuous Deployment)는 코드 변경 시 자동으로 빌드, 테스트, 배포 과정을 실행하여 개발 프로세스를 효율화합니다.
GitHub Actions를 사용한 CI 설정
워크플로우 파일 생성
.github/workflows/ci.yml
name: C/C++ CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up CMake
uses: lukka/get-cmake@v3
- name: Build
run: |
cmake -B build -S .
cmake --build build
- name: Run Tests
run: |
cd build
ctest --output-on-failure
- actions/checkout@v3: 리포지토리를 체크아웃합니다.
- lukka/get-cmake@v3: CMake를 설정합니다.
- 빌드와 테스트를 수행합니다.
GitLab CI/CD를 사용한 CI 설정
.gitlab-ci.yml 파일 생성
stages:
- build
- test
build:
stage: build
script:
- cmake -B build -S .
- cmake --build build
artifacts:
paths:
- build/
test:
stage: test
script:
- cd build
- ctest --output-on-failure
- stages: 빌드와 테스트 단계를 정의합니다.
- artifacts: 빌드 결과물을 다음 단계로 전달합니다.
Docker를 활용한 빌드 환경 통일
Docker를 사용하면 모든 개발자와 CI/CD 시스템에서 동일한 빌드 환경을 사용할 수 있습니다.
Dockerfile 예제
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
lcov
WORKDIR /app
COPY . .
RUN cmake -B build -S .
RUN cmake --build build
RUN cd build && ctest
- 필요한 패키지를 설치하고, 소스를 복사하여 빌드와 테스트를 수행합니다.
Docker를 이용한 로컬 빌드 및 테스트
docker build -t my_project_image .
docker run my_project_image
- Docker 이미지를 빌드하고 실행하여 테스트를 수행합니다.
CD(Continuous Deployment) 설정
배포 자동화를 위해 CD 파이프라인을 구축할 수 있습니다. 빌드된 결과물을 패키징하여 배포하거나, 컨테이너 이미지를 생성하여 배포 서버에 배포합니다.
예제: Docker 이미지를 Docker Hub에 푸시
GitHub Actions 워크플로우 업데이트
jobs:
build-test-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker Image
run: docker build -t myusername/myproject:latest .
- name: Log in to Docker Hub
run: echo "${{ secrets.DOCKER_HUB_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin
- name: Push Docker Image
run: docker push myusername/myproject:latest
- Docker Hub에 로그인하여 이미지를 푸시합니다.
- secrets를 사용하여 민감한 정보를 보호합니다.
결론
이번 글에서는 CMake를 활용한 테스트 설정과 CI/CD 파이프라인 연동 방법에 대해 알아보았습니다. 이를 통해 자동화된 빌드와 테스트 환경을 구축하여 개발 효율성과 코드 품질을 높일 수 있습니다.
다음 글에서는 CMake의 고급 기능인 생성기 표현식과 커스텀 명령어, 그리고 대규모 프로젝트에서의 모던 CMake 활용 방법에 대해 살펴보겠습니다.
'개발 이야기 > CMake' 카테고리의 다른 글
[모던 CMake] 크로스 컴파일과 툴체인 파일 활용 (0) | 2024.12.04 |
---|---|
[모던 CMake] 생성기 표현식과 커스텀 명령어 활용 (0) | 2024.12.03 |
[모던 CMake] 외부 라이브러리와 패키지 관리 (0) | 2024.12.01 |
[모던 CMake] 타겟 기반 구성과 의존성 관리 (32) | 2024.11.30 |
[모던 CMake] C++ 표준 버전 설정 방법 비교 (16) | 2024.11.30 |