如何用CMake合并多个测试用例实现单次运行结果统计
问题描述
我用CMake构建并测试C语言代码,已创建多个独立测试用例,但每次单独运行测试时,每个测试都会显示“100% 1/1”的结果。我希望将这些测试合并为一次运行,最终显示汇总统计,比如“100% 4/4”(全部通过)或“75% tests passed, 1 tests failed out of 4”(存在失败)。
当前代码
CMakeLists.txt
cmake_minimum_required(VERSION 3.16) project(my_project) set(CMAKE_C_STANDARD 11) add_executable(my_project main.c) enable_testing() add_test(NAME build_test COMMAND ${CMAKE_COMMAND} --build .) add_test(NAME run_test COMMAND my_project) set_tests_properties(run_test PROPERTIES DEPENDS build_test) add_test(NAME output_test COMMAND my_project 3) set_tests_properties(output_test PROPERTIES PASS_REGULAR_EXPRESSION "Hello, World!\nHello, World!\nHello, World!") add_test(NAME output_test2 COMMAND my_project 5) set_tests_properties(output_test2 PROPERTIES PASS_REGULAR_EXPRESSION "Hello, World!\nHello, World!\nHello, World!\nHello, World!\nHello, World!\n")
main.c
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int n = atoi(argv[1]); for(int i = 0; i < n; i++) { printf("Hello, World!\n"); } return 0; }
当前测试输出示例
[ctest] Start 1: build_test [ctest] 1/1 Test #1: build_test ....................... Passed 0.55 sec [ctest] [ctest] 100% tests passed, 0 tests failed out of 1
期望输出示例
全部通过时
[ctest] Start 1: combined_test [ctest] 4/4 Test #1: combined_test ................... Passed 0.55 sec [ctest] [ctest] 100% tests passed, 0 tests failed out of 4
存在失败时
[ctest] Start 1: combined_test [ctest] 4/4 Test #1: combined_test ................... Passed 0.55 sec [ctest] [ctest] 75% tests passed, 1 tests failed out of 4
解决方案
将多个测试逻辑整合到自定义脚本中,让CTest执行该脚本,脚本内部统计所有测试用例的结果并返回整体状态。
步骤1:创建测试脚本run_all_tests.sh
#!/bin/bash total_tests=4 passed_tests=0 # 测试1:构建项目 echo "Running build_test..." cmake --build . if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)) echo "build_test: PASSED" else echo "build_test: FAILED" fi # 测试2:运行程序(修复无参数崩溃问题,默认传1) echo "Running run_test..." ./my_project 1 if [ $? -eq 0 ]; then passed_tests=$((passed_tests + 1)) echo "run_test: PASSED" else echo "run_test: FAILED" fi # 测试3:输出3次Hello World echo "Running output_test..." output=$("./my_project" 3) expected="Hello, World! Hello, World! Hello, World!" if [ "$output" == "$expected" ]; then passed_tests=$((passed_tests + 1)) echo "output_test: PASSED" else echo "output_test: FAILED" fi # 测试4:输出5次Hello World echo "Running output_test2..." output=$("./my_project" 5) expected="Hello, World! Hello, World! Hello, World! Hello, World! Hello, World!" if [ "$output" == "$expected" ]; then passed_tests=$((passed_tests + 1)) echo "output_test2: PASSED" else echo "output_test2: FAILED" fi # 输出汇总统计 echo "" echo "$passed_tests/$total_tests tests passed" [ $passed_tests -eq $total_tests ] && exit 0 || exit 1
步骤2:修改CMakeLists.txt
替换原有的多个add_test配置,改为执行上述脚本:
cmake_minimum_required(VERSION 3.16) project(my_project) set(CMAKE_C_STANDARD 11) add_executable(my_project main.c) enable_testing() # 添加合并后的测试 add_test(NAME combined_test COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run_all_tests.sh) # 确保脚本可执行 file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/run_all_tests.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
步骤3:修复main.c无参数崩溃问题
原代码在无参数时访问argv[1]会触发未定义行为,修改为:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { int n = 1; // 设置默认值 if (argc > 1) { n = atoi(argv[1]); } for(int i = 0; i < n; i++) { printf("Hello, World!\n"); } return 0; }
效果说明
运行ctest时,会执行combined_test任务,脚本内部依次运行4个测试用例,输出每个测试的结果后展示汇总统计。CTest会根据脚本的退出码判断整体测试是否通过,同时你可以在控制台清晰看到总测试数及通过率。
内容的提问来源于stack exchange,提问作者MorpKnight
相关产品推荐
相关产品推荐

