如何配置CMake项目,集成Google Test并适配CTest?
把GTest集成到CMake项目的完整指南
问得好!咱们一步步来搞定GTest和CMake的集成,满足你创建独立测试可执行文件、灵活选择测试范围的需求,顺便也讲下可选的CTest适配方法!
第一步:选择GTest的引入方式
我推荐用CMake的FetchContent模块自动拉取GTest,不用手动安装,跨平台更省心;如果你的系统已经通过包管理器装了GTest,也可以用FindGTest,不过FetchContent更利于项目的可移植性。
用FetchContent引入GTest
在主CMakeLists.txt开头添加这段代码:
cmake_minimum_required(VERSION 3.14) # FetchContent需要至少3.14版本 project(YourProjectName) # 启用测试(为CTest适配做准备) enable_testing() # 引入FetchContent模块 include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip ) # Windows环境下,强制使用和项目一致的CRT set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest)
用系统已安装的GTest
如果系统已经装了GTest,直接用这段:
find_package(GTest REQUIRED) enable_testing()
第二步:梳理项目结构(建议)
假设你的项目是经典的源码+测试分离结构(如果不是,调整路径适配即可):
YourProject/ ├── src/ │ ├── module_a/ │ │ ├── module_a.cpp │ │ └── module_a.h │ ├── module_b/ │ │ ├── module_b.cpp │ │ └── module_b.h │ └── CMakeLists.txt ├── tests/ │ ├── test_module_a.cpp │ ├── test_module_b.cpp │ └── CMakeLists.txt └── CMakeLists.txt
第三步:主CMakeLists.txt配置
主文件里除了GTest引入代码,还要把源码和测试目录加入构建:
# ... 前面的GTest引入代码 ... # 添加源码子目录(假设src下的CMakeLists.txt已将模块编译为库) add_subdirectory(src) # 添加测试子目录 add_subdirectory(tests)
第四步:测试目录的CMakeLists.txt配置(核心!)
这里实现独立测试可执行文件,同时支持单个模块或全项目测试,有两种方案可选:
方案1:每个模块对应一个独立测试可执行文件
这种方式可以单独运行某个模块的测试,也能一键跑完全部测试。在tests/CMakeLists.txt中写入:
# 模块A的测试可执行文件 add_executable(test_module_a test_module_a.cpp) target_link_libraries(test_module_a PRIVATE module_a GTest::gtest_main) # 将测试加入CTest add_test(NAME TestModuleA COMMAND test_module_a) # 模块B的测试可执行文件 add_executable(test_module_b test_module_b.cpp) target_link_libraries(test_module_b PRIVATE module_b GTest::gtest_main) add_test(NAME TestModuleB COMMAND test_module_b) # 可选:创建自定义目标,一键运行所有测试 add_custom_target(run_all_tests COMMAND ${CMAKE_CTEST_COMMAND} --verbose DEPENDS test_module_a test_module_b COMMENT "Running all tests..." )
方案2:单个可执行文件,支持GTest测试过滤
如果只想生成一个测试可执行文件,但能通过命令行选择测试范围,用这种方式:
add_executable(all_tests test_module_a.cpp test_module_b.cpp) target_link_libraries(all_tests PRIVATE module_a module_b GTest::gtest_main) add_test(NAME AllTests COMMAND all_tests)
运行时用GTest的过滤参数即可:
# 只运行模块A的所有测试 ./tests/all_tests --gtest_filter=ModuleA* # 只运行模块A下的某个具体测试用例 ./tests/all_tests --gtest_filter=ModuleA.TestCaseName
第五步:如何运行测试
运行单个模块测试
- 方案1:直接执行对应测试可执行文件
./tests/test_module_a - 方案2:用GTest过滤参数
./tests/all_tests --gtest_filter=ModuleA*
运行全部测试
- 方案1:使用自定义目标(如果配置了的话)
make run_all_tests # 或 ninja run_all_tests,取决于你用的构建器 - 或直接用CTest:
ctest --verbose # --verbose参数可以查看详细测试输出
第六步:适配CTest(可选)
前面的配置已经将测试加入CTest了,你还可以给测试分组、设置超时等,让CTest更贴合需求:
# 给测试分组,方便按组过滤运行 set_tests_properties(TestModuleA PROPERTIES LABELS "ModuleA") set_tests_properties(TestModuleB PROPERTIES LABELS "ModuleB") # 运行时按组过滤:ctest -L ModuleA
如果需要更复杂的配置(比如测试依赖、超时时间),可以参考CMake的set_tests_properties文档。
注意事项
- 确保你的源码模块(比如
module_a)是用add_library生成的库目标,这样测试可执行文件才能正确链接它。 - GTest的
gtest_main已经帮你实现了main函数,测试文件里不用手动编写main,直接用TEST或TEST_F宏写测试用例即可。 - 如果需要自定义main函数逻辑,链接
GTest::gtest而非GTest::gtest_main,然后自己实现main函数。
内容的提问来源于stack exchange,提问作者Arnav Garg
相关产品推荐
相关产品推荐

