[C/C++] 개발 환경 구성하기 01 (아키텍처 설계, 브랜치 전략)
[C/C++] 개발 환경 구성하기 02 (cmake, libft, google test)
[C/C++] 개발 환경 구성하기 03 (gcovr, codecov)
[C/C++] 개발 환경 구성하기 04 (github action, norminette, codecov)
[C/C++] 개발 환경 구성하기 05 (miniLibX)
지난번에 이어서 이번에는 google test와 gcovr를 연동하는 방법에 대해 공유하도록 하겠습니다.
google test
google test는 c++ 단위 테스트 프레임워크입니다. 다양한 조건의 assertion과 커스터마징(pre-test, post-test 등)을 지원하기 때문에 테스트를 작성하는데 많은 도움을 줍니다.
다만 c 코드를 테스트하기 위해서는 extern "C"를 사용하여 C++ 컴파일러에게 해당 코드가 C 언어로 작성되었음을 알려주어 네임 맹글링(name mangling)을 방지해야합니다.
extern "C"를 사용하여 네임 맹글링을 방지하는 방법에는 다음과 같이 2가지 방식이 있습니다.
1. 헤더 파일에 명시
#ifndef VEC3_H
# define VEC3_H
# ifdef __cplusplus
extern "C" {
# endif
// ...
# ifdef __cplusplus
}
# endif
#endif
2. #include 지시문에서 명시
extern "C" {
#include "ray.h"
}
#include "gtest/gtest.h"
TEST(RayTest, RayTest_ray)
{
// assertions
}
42서울 과제에서는 norminette를 위해 추후에 c++에 대한 의존성을 제거해야하므로 두 번째 방법을 사용하는 것이 좋을 것 같습니다.
gcovr
gcovr는 GCC의 gcov 유틸리티를 기반으로 하는 코드 커버리지 분석 도구입니다. gcov는 프로그램이 실행되는 동안 소스 코드의 어느 부분이 실행되었는지를 분석하여, 테스트 커버리지 정보를 제공합니다. gcovr은 gcov의 데이터를 사용하여 HTML, XML, JSON 등 다양한 형식의 레포트를 생성하며, 지속적으로 모니터링할 수 있도록 다양한 CI 시스템과 통합할 수 있습니다.
gcovr를 사용하기 위해서는 --coverage(fprofile-arcs -ftest-coverage와 동일) 옵션을 사용하여 컴파일해야합니다. --coverage 옵션으로 컴파일된 테스트 실행 파일을 실행하면 커버리지를 분석한 .gcda 파일을 생성합니다. gcovr 명령어를 실행하면 .gcda 파일을 통해 원하는 형식의 레포트를 생성합니다.
# ...
option(ENABLE_COVERAGE "Enable coverage" OFF)
if(ENABLE_COVERAGE)
add_compile_options(--coverage)
link_libraries(--coverage)
endif()
# ...
# build coverage
add_custom_target(coverage
COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -print0 | xargs -0 rm
COMMAND ${CMAKE_COMMAND} -B${CMAKE_BINARY_DIR} -DENABLE_COVERAGE=ON ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${TEST_NAME}
COMMAND ${CMAKE_BINARY_DIR}/${TEST_NAME}
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/reports
COMMAND gcovr -r ${CMAKE_SOURCE_DIR}
-e '${CMAKE_BINARY_DIR}/_deps/*'
-e '${CMAKE_SOURCE_DIR}/test/*'
--html --html-details
-o '${CMAKE_BINARY_DIR}/reports/test-coverage.html'
COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -print0 | xargs -0 rm
COMMAND rm -f ${CMAKE_BINARY_DIR}/${TEST_NAME} ${CMAKE_BINARY_DIR}/${EXEC_NAME}
저는 coverage라는 build target을 정의해서 레포트를 생성했습니다. 위 코드에서 CMAKE_BIRNARY_DIR은 build 폴더를 의미합니다. ENABLE_COVERGAE라는 옵션을 설정해서 해당 옵션이 ON인 경우 컴파일시 --coverage 옵션을 추가하도록 설정했습니다. CLI 환경에서 cmake를 사용하여 컴파일할때 -B 옵션을 사용해서 빌드 폴더를 지정하고, -D 옵션을 사용해서 ENABLE_COVERGAE을 ON으로 설정했습니다.
테스트를 실행하면 .gcda 분석 파일이 생성됩니다. -r(--root) 옵션은 커버리지 데이터를 수집하는 루트 디렉토리를 설정하는 옵션이고, -e(--exclude) 옵션은 제외할 커버리지 데이터를 의미합니다. 여기서는 외부 라이브러리와 테스트 코드를 제외하기위해 _deps와 test 폴더를 제외했습니다.
마지막으로 기존의 .gcda 분석 파일이 다음 커버리지 레포트를 생성하는데 영향을 주지 않도록 기존의 .gcda 파일과 테스트 실행파일을 삭제했습니다.
이제 VSCode의 Command Palette(Command + Shift + P)에서 CMake: Build Target을 선택하고 저희가 커스텀을 생성한 coverage를 선택하면 위와 같이 ./build/reports/test-coverage.html 경로에 레포트를 생성합니다.
참고자료
Codecov를 이용한 C++ 코드 커버리지 측정 방법
'C & C++' 카테고리의 다른 글
[C/C++] C 언어에서 상속과 다형성 구현하기 (0) | 2024.07.29 |
---|---|
[C/C++] 개발 환경 구성하기 05 (miniLibX) (0) | 2024.07.23 |
[C/C++] 개발 환경 구성하기 04 (github action, norminette, codecov) (1) | 2024.07.22 |
[C/C++] 개발 환경 구성하기 02 (cmake, libft, google test) (1) | 2024.07.22 |
[C/C++] 개발 환경 구성하기 01 (아키텍처 설계, 브랜치 전략) (0) | 2024.07.21 |