Skip to content

GoogleTest 集成方式 CMake 与包管理

GoogleTest 可以通过系统安装、源码子目录、FetchContent、包管理器等方式集成。工程中应优先选择可重复构建、版本清晰、对 CI 友好的方式。

GoogleTest 集成方式

方式一:系统安装后 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
交叉编译 工具链预构建包或源码子目录