GoogleTest 集成方式 CMake 与包管理
GoogleTest 可以通过系统安装、源码子目录、FetchContent、包管理器等方式集成。工程中应优先选择可重复构建、版本清晰、对 CI 友好的方式。
方式一:系统安装后 find_package
适合 Linux 发行版包、vcpkg、Conan 或公司内部工具链已经提供 GoogleTest 的场景。
find_package(GTest REQUIRED)
add_executable(unit_tests
tests/example_test.cpp)
target_link_libraries(unit_tests
PRIVATE GTest::gtest_main)
优点是 CMakeLists 简洁。缺点是不同机器上的 GoogleTest 版本可能不一致,需要通过工具链或包管理器约束。
方式二:FetchContent
适合中小项目或希望 CMake 自动下载依赖的项目。
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
add_executable(unit_tests
tests/example_test.cpp)
target_link_libraries(unit_tests
PRIVATE GTest::gtest_main)
在 Windows + MSVC 下,gtest_force_shared_crt 常用于让 GoogleTest 使用和工程一致的运行时库设置。
方式三:源码子目录
适合不能访问网络、需要把第三方源码固定在仓库或镜像中的项目。
third_party
googletest
CMakeLists.txt
add_subdirectory(third_party/googletest)
add_executable(unit_tests
tests/example_test.cpp)
target_link_libraries(unit_tests
PRIVATE GTest::gtest_main)
优点是构建可重复,缺点是仓库体积变大,升级依赖需要维护第三方源码。
方式四:vcpkg
安装:
vcpkg install gtest
CMake 配置:
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
CMakeLists:
find_package(GTest CONFIG REQUIRED)
target_link_libraries(unit_tests PRIVATE GTest::gtest GTest::gtest_main)
方式五:Conan
conanfile.txt 示例:
[requires]
gtest/1.14.0
[generators]
CMakeDeps
CMakeToolchain
构建:
conan install . --output-folder=build --build=missing
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
接入 CTest
GoogleTest 可执行文件可以直接运行,也可以交给 CTest 管理。
enable_testing()
include(GoogleTest)
gtest_discover_tests(unit_tests
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS unit)
gtest_discover_tests 会运行测试程序的 --gtest_list_tests 来发现测试。相比手写 add_test,它能把每个 GoogleTest 测试注册成独立 CTest 测试,失败报告更细。
gtest_add_tests 与 gtest_discover_tests
| API | 发现方式 | 优点 | 局限 |
|---|---|---|---|
gtest_add_tests |
配置阶段扫描源码 | 不需要运行测试程序 | 宏写法复杂时可能漏发现 |
gtest_discover_tests |
构建后运行测试程序列出测试 | 发现结果更准确 | 交叉编译或运行环境受限时需额外配置 |
多测试目标组织
大型工程不要把所有测试塞进一个巨大可执行文件。可以按模块拆分:
add_executable(core_tests tests/core_test.cpp)
target_link_libraries(core_tests PRIVATE core_lib GTest::gtest_main)
gtest_discover_tests(core_tests PROPERTIES LABELS unit)
add_executable(io_tests tests/io_test.cpp)
target_link_libraries(io_tests PRIVATE io_lib GTest::gtest_main)
gtest_discover_tests(io_tests PROPERTIES LABELS integration)
运行:
ctest --test-dir build -L unit --output-on-failure
ctest --test-dir build -L integration --output-on-failure
覆盖率编译选项
GCC 或 Clang 生成 gcov 覆盖率数据时,常见编译链接选项如下:
option(ENABLE_COVERAGE "Enable coverage flags" OFF)
if(ENABLE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
add_compile_options(--coverage -O0 -g)
add_link_options(--coverage)
endif()
覆盖率构建应使用单独构建目录,避免污染普通 Debug 或 Release 构建。
cmake -S . -B build-coverage -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build-coverage
ctest --test-dir build-coverage --output-on-failure
集成方式选择
| 项目条件 | 推荐方式 |
|---|---|
| 公司统一工具链 | find_package |
| 开源小项目 | FetchContent |
| 离线构建要求强 | 源码子目录或内部镜像 |
| 依赖较多且跨平台 | vcpkg 或 Conan |
| 交叉编译 | 工具链预构建包或源码子目录 |