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_main、gtest_discover_tests等目标与命令在仓库源码中的底层含义。前置准备Prerequisites在开始之前请确认你的开发环境满足以下条件操作系统Linux、macOS、Windows 等受支持的平台之一详见仓库中的 docs/platforms.mdC 编译器支持至少 C14 标准的编译器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 C14 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 projects 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 自身要求 C14 起步。这与仓库源码一致——在 googletest/cmake/internal_utils.cmake 中gtest/gtest_main库通过target_compile_features(${name} PUBLIC cxx_std_14)强制要求 C14 编译特性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 的项目通常建议设为OFFGTEST_HAS_ABSLOFF是否使用 Abseil 与 RE2需要额外把它们加入构建在 googletest/CMakeLists.txt 中还会定义gtest_force_shared_crt、gtest_build_tests构建 gtest 自身测试默认OFF、gtest_build_samples构建官方示例程序默认OFF、gtest_disable_pthreads、gtest_hide_internal_symbols等选项。当 GoogleTest 被作为子项目嵌入时即本例场景这些选项会被标记为 advanced只有当CMAKE_PROJECT_NAME等于gtest或googletest-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); }这段代码做了两件事#include gtest/gtest.h引入 GoogleTest 公共头文件 googletest/include/gtest/gtest.h它定义了TEST、EXPECT_*等全部公开宏与 APITEST(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 ...并依次完成初始化和运行全部测试因此测试文件里不需要再写maininclude(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::gtest与GTest::gtest_main是等价的导出命名。如果你选择将 GoogleTest 安装到系统INSTALL_GTESTON时仓库还会通过 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三个命令的职责cmake -S . -B build以源码目录.配置到构建目录build-S/-B是 CMake 3.13 的推荐写法本仓库顶层 CMakeLists.txt 同样要求cmake_minimum_required(VERSION 3.13)。此时FetchContent会下载并解压 GoogleTest随后构建其gtest、gtest_main、gmock等目标cmake --build build编译全部目标最终生成hello_test可执行文件cd build ctest通过 CTest 运行已注册的测试。由于gtest_discover_tests的动态发现机制HelloTest.BasicAssertions被自动识别为测试 #1 并显示Passed。从输出可以看到[100%] Built target gmock_main即使你的例子只用到 gtestFetchContent_MakeAvailable默认也会一并构建 googlemock顶层 CMakeLists.txt 中BUILD_GMOCK默认为ON。如果希望关闭该子项目可在FetchContent_MakeAvailable之前设置set(BUILD_GMOCK OFF)。至此你已经成功用 CMake GoogleTest 构建并运行了第一个测试二进制。延伸构建 GoogleTest 自身的测试与示例如果你希望在本仓库中验证 GoogleTest 自身的测试套件可以把它当作主项目直接构建仓库是只读的仅作查看与运行cmake -S . -B build -Dgtest_build_testsON cmake --build build ctest-Dgtest_build_testsON会开启 googletest/CMakeLists.txt 中的全部自测目标涵盖 C 测试如gtest_unittest、googletest-death-test-test、googletest-param-test-test、非标准编译配置测试禁用异常、禁用 RTTI以及 Python 脚本测试-Dgtest_build_samplesON会构建 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),仅供参考