GoogleTest 与 CMake 快速上手:从零搭建基于 FetchContent 的 C++ 单元测试工程
2026/9/19 4:45:04 网站建设 项目流程

GoogleTest 与 CMake 快速上手:从零搭建基于 FetchContent 的 C++ 单元测试工程

【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/gh_mirrors/googl/googletest

本教程以当前仓库(GoogleTest 1.14.0 发行版源码)为依托,完整讲解如何用 CMake 将 GoogleTest 以FetchContent方式引入自己的 C++ 项目,编写并运行第一个单元测试二进制。读完本文,你将掌握一套可复制的 CMake 工程骨架:从CMakeLists.txt声明依赖、TEST()宏编写断言,到cmake构建、ctest自动发现并运行测试的完整链路,并理解GTest::gtest_maingtest_discover_tests等目标与命令在仓库源码中的底层含义。

前置准备(Prerequisites)

在开始之前,请确认你的开发环境满足以下条件:

  • 操作系统:Linux、macOS、Windows 等受支持的平台之一,详见仓库中的 docs/platforms.md;
  • C++ 编译器:支持至少 C++14 标准的编译器(GCC、Clang、MSVC 均可);
  • CMake 与构建工具:CMake 3.14 及以上版本,以及配套的构建工具,如 GNU Make、Ninja 等(可参考 CMake Generators 文档了解不同生成器)。

教程中的终端命令以 Unix shell 提示符展示,但同样适用于 Windows 命令行(本仓库 CI 中即同时维护了 ci/linux-presubmit.sh、ci/macos-presubmit.sh 与 ci/windows-presubmit.bat 三类平台的预检脚本,可见其跨平台一致性是官方持续验证的)。

如果你还没安装 CMake,请先完成 CMake 的安装;若使用 Bazel 构建系统,可改看 docs/quickstart-bazel.md。

第一步:建立项目并声明 GoogleTest 依赖

CMake 通过项目根目录下的CMakeLists.txt文件描述构建系统。首先创建一个项目目录:

$ mkdir my_project && cd my_project

my_project下创建CMakeLists.txt,内容如下:

cmake_minimum_required(VERSION 3.14) project(my_project) # GoogleTest requires at least C++14 set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest)

配置逐行解析

  • cmake_minimum_required(VERSION 3.14)FetchContent在 CMake 3.14 中成为稳定功能,因此这是使用该模块的最低版本要求;
  • set(CMAKE_CXX_STANDARD 14)set(CMAKE_CXX_STANDARD_REQUIRED ON):GoogleTest 自身要求 C++14 起步。这与仓库源码一致——在 googletest/cmake/internal_utils.cmake 中,gtest/gtest_main库通过target_compile_features(${name} PUBLIC cxx_std_14)强制要求 C++14 编译特性;
  • include(FetchContent)+FetchContent_Declare(...):声明外部依赖googletest,此处通过 URL 指向某个 commit 的 ZIP 归档;
  • set(gtest_force_shared_crt ON CACHE BOOL "" FORCE):Windows 专用设置,防止 GoogleTest 覆盖父项目的编译器/链接器设置。该选项定义于 googletest/CMakeLists.txt,其作用是"即使 GoogleTest 以静态库构建,也强制使用共享(DLL)运行库";
  • FetchContent_MakeAvailable(googletest):将依赖以子目录方式引入当前构建,等价于把仓库的 CMakeLists.txt 加入构建图。

URL 里的 commit 是什么?

示例中的03597a01ee50ed33e9dfd640b249b4be3799d395是 GoogleTest 仓库某个版本的 Git commit 哈希,用于锁定精确版本。官方建议经常更新该哈希以指向最新版本(可使用main分支上较新的 commit)。作为对比,当前仓库的 googletest/CMakeLists.txt 中定义了GOOGLETEST_VERSION 1.14.0,即本仓库对应的发行版本号。

被引入后发生了什么(源码视角)

当你通过FetchContent引入 GoogleTest 时,其顶层 CMakeLists.txt 会被执行,它定义了几个关键构建选项:

选项默认值说明
BUILD_GMOCKON是否同时构建 googlemock 子项目(注意:googlemock 目标已经会连带构建 googletest,见 CMakeLists.txt 的注释)
INSTALL_GTESTON是否安装 googletest;嵌入式使用 GoogleTest 的项目通常建议设为OFF
GTEST_HAS_ABSLOFF是否使用 Abseil 与 RE2(需要额外把它们加入构建)

在 googletest/CMakeLists.txt 中还会定义gtest_force_shared_crtgtest_build_tests(构建 gtest 自身测试,默认OFF)、gtest_build_samples(构建官方示例程序,默认OFF)、gtest_disable_pthreadsgtest_hide_internal_symbols等选项。当 GoogleTest 被作为子项目嵌入时(即本例场景),这些选项会被标记为 advanced;只有当CMAKE_PROJECT_NAME等于gtestgoogletest-distribution时(即 GoogleTest 本身就是主项目),才会额外暴露BUILD_SHARED_LIBS(见 googletest/CMakeLists.txt)。

第二步:编写第一个测试二进制

依赖声明完成后,就可以在你的工程中直接使用 GoogleTest 的代码了。在my_project目录下创建hello_test.cc

#include <gtest/gtest.h> // Demonstrate some basic assertions. TEST(HelloTest, BasicAssertions) { // Expect two strings not to be equal. EXPECT_STRNE("hello", "world"); // Expect equality. EXPECT_EQ(7 * 6, 42); }

这段代码做了两件事:

  1. #include <gtest/gtest.h>:引入 GoogleTest 公共头文件 googletest/include/gtest/gtest.h,它定义了TESTEXPECT_*等全部公开宏与 API;
  2. TEST(HelloTest, BasicAssertions):定义了一个名为BasicAssertions、隶属于测试套件HelloTest的测试。TEST()宏是 GoogleTest 的基础测试写法,更完整的断言体系可参考 docs/primer.md 与 docs/reference/assertions.md。

这里的EXPECT_STRNE是非致命断言,失败时不会中断当前测试函数;EXPECT_EQ检查两个值是否相等。测试结果由断言决定:任一断言失败(致命或非致命)或测试崩溃,整个测试即失败;否则成功。关于测试套件(Test Suite)、测试(Test)与断言(Assertion)的术语体系与 xUnit 架构背景,可进一步阅读 docs/primer.md。

第三步:把测试接入 CMake 构建与 ctest

CMakeLists.txt末尾追加以下内容:

enable_testing() add_executable( hello_test hello_test.cc ) target_link_libraries( hello_test GTest::gtest_main ) include(GoogleTest) gtest_discover_tests(hello_test)

逐段说明:

  • enable_testing():开启 CTest 支持;
  • add_executable(hello_test hello_test.cc):声明要构建的测试二进制;
  • target_link_libraries(hello_test GTest::gtest_main):链接 GoogleTest 的gtest_main目标。这里用的是gtest_main而非gtest——两者的区别在于:gtest是纯框架库,需要你自己写main()并调用testing::InitGoogleTest()RUN_ALL_TESTS();而gtest_main在 googletest/src/gtest_main.cc 中已内置了标准main(),会输出Running main() from ...并依次完成初始化和运行全部测试,因此测试文件里不需要再写main
  • include(GoogleTest)+gtest_discover_tests(hello_test):借助 CMake 官方的GoogleTest模块,在ctest 阶段动态枚举hello_test二进制中的全部测试用例并注册为 CTest 测试项,无需手工逐个add_test()

链接目标命名从何而来

GTest::gtest_main这种带命名空间的目标,由仓库构建脚本生成:在 googletest/cmake/internal_utils.cmake 中,add_library(${cmake_package_name}::${name} ALIAS ${name})cmake_package_name = GTest为前缀创建了别名目标(见 googletest/CMakeLists.txt)。因此链接名GTest::gtestGTest::gtest_main是等价的导出命名。如果你选择将 GoogleTest 安装到系统(INSTALL_GTEST=ON时),仓库还会通过 googletest/cmake/Config.cmake.in 生成可被find_package(GTest)消费的包配置文件。

第四步:构建并运行测试

在项目根目录依次执行:

my_project$ cmake -S . -B build -- The C compiler identification is GNU 10.2.1 -- The CXX compiler identification is GNU 10.2.1 ... -- Build files have been written to: .../my_project/build my_project$ cmake --build build Scanning dependencies of target gtest ... [100%] Built target gmock_main my_project$ cd build && ctest Test project .../my_project/build Start 1: HelloTest.BasicAssertions 1/1 Test #1: HelloTest.BasicAssertions ........ Passed 0.00 sec 100% tests passed, 0 tests failed out of 1 Total Test time (real) = 0.01 sec

三个命令的职责:

  1. cmake -S . -B build:以源码目录.配置到构建目录build-S/-B是 CMake 3.13+ 的推荐写法,本仓库顶层 CMakeLists.txt 同样要求cmake_minimum_required(VERSION 3.13))。此时FetchContent会下载并解压 GoogleTest,随后构建其gtestgtest_maingmock等目标;
  2. cmake --build build:编译全部目标,最终生成hello_test可执行文件;
  3. cd build && ctest:通过 CTest 运行已注册的测试。由于gtest_discover_tests的动态发现机制,HelloTest.BasicAssertions被自动识别为测试 #1 并显示Passed

从输出可以看到[100%] Built target gmock_main:即使你的例子只用到 gtest,FetchContent_MakeAvailable默认也会一并构建 googlemock(顶层 CMakeLists.txt 中BUILD_GMOCK默认为ON)。如果希望关闭该子项目,可在FetchContent_MakeAvailable之前设置set(BUILD_GMOCK OFF)

至此,你已经成功用 CMake + GoogleTest 构建并运行了第一个测试二进制。

延伸:构建 GoogleTest 自身的测试与示例

如果你希望在本仓库中验证 GoogleTest 自身的测试套件,可以把它当作主项目直接构建(仓库是只读的,仅作查看与运行):

cmake -S . -B build -Dgtest_build_tests=ON cmake --build build ctest
  • -Dgtest_build_tests=ON会开启 googletest/CMakeLists.txt 中的全部自测目标,涵盖 C++ 测试(如gtest_unittestgoogletest-death-test-testgoogletest-param-test-test)、非标准编译配置测试(禁用异常、禁用 RTTI)以及 Python 脚本测试;
  • -Dgtest_build_samples=ON会构建 googletest/samples 下的官方示例程序,例如sample1_unittest演示了函数级测试与测试夹具,sample8_unittest演示了值参数化测试等。更多示例说明见 docs/samples.md。

下一步学习路径

  • 阅读 docs/primer.md,系统学习TEST()TEST_F()测试夹具、断言与测试套件的组织方式;
  • 浏览 docs/reference/assertions.md 与 docs/reference/matchers.md,掌握完整的断言与匹配器清单;
  • 查看 googletest/samples 与 docs/samples.md,了解 GoogleTest 各类特性的真实用法;
  • 若你的工程使用 Bazel,参考 docs/quickstart-bazel.md;仓库根目录还提供了 BUILD.bazel、WORKSPACE 与 MODULE.bazel 供 Bazel 用户直接引用。

【免费下载链接】googletestGoogleTest - Google Testing and Mocking Framework项目地址: https://gitcode.com/gh_mirrors/googl/googletest

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询