You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中doctest独立测试主函数无法识别生产代码内测试的问题

解决方案

核心思路

doctest默认会在非测试编译环境下禁用测试代码,所以需要通过预定义宏+CMake配置,让生产代码中的测试仅在编译测试二进制时被激活,同时将生产代码逻辑与测试代码合并到同一测试可执行文件中,且不影响原生产main函数。


1. 生产代码中包裹测试逻辑

在src目录的源文件中,用#ifdef DOCTEST_INCLUDE_TESTS包裹测试代码,确保只有编译测试时才会包含这部分代码,生产编译时自动排除:

// src/foo.cpp
// 生产逻辑代码
int add(int a, int b) {
    return a + b;
}

// 仅在测试编译时生效的测试代码
#ifdef DOCTEST_INCLUDE_TESTS
#include <doctest/doctest.h>
TEST_CASE("add函数功能验证") {
    CHECK(add(1, 2) == 3);
    CHECK(add(-1, 1) == 0);
}
#endif

注意:不要在头文件中写测试代码,避免因头文件被多次包含导致测试用例重复定义。


2. 调整CMake配置

通过CMake区分生产编译和测试编译的宏定义,同时将生产代码逻辑链接到测试可执行文件中:

推荐方案:将生产代码封装为库

# 1. 编译生产代码为静态库(分离逻辑与入口)
add_library(my_project_lib STATIC
    src/foo.cpp
    src/bar.cpp
)

# 2. 生产可执行文件(保留原main函数)
add_executable(my_project src/main.cpp)
target_link_libraries(my_project PRIVATE my_project_lib)

# 3. 测试可执行文件
add_executable(my_project_test
    test/test_main.cpp
    test/complex_test.cpp  # 独立复杂测试文件
)
# 编译测试时定义宏,激活生产代码中的测试
target_compile_definitions(my_project_test PRIVATE DOCTEST_INCLUDE_TESTS)
# 链接生产库,将生产代码中的测试逻辑引入测试二进制
target_link_libraries(my_project_test PRIVATE my_project_lib)
# 指定doctest头文件路径(根据实际路径调整)
target_include_directories(my_project_test PRIVATE ${CMAKE_SOURCE_DIR}/third_party/doctest)

备选方案:直接复用生产源文件(不封装库)

如果不想封装库,可将生产源文件(除main.cpp外)直接加入测试可执行的编译列表:

# 生产可执行文件
add_executable(my_project
    src/main.cpp
    src/foo.cpp
    src/bar.cpp
)

# 测试可执行文件(不包含src/main.cpp,避免多main冲突)
add_executable(my_project_test
    test/test_main.cpp
    test/complex_test.cpp
    src/foo.cpp
    src/bar.cpp
)
target_compile_definitions(my_project_test PRIVATE DOCTEST_INCLUDE_TESTS)
target_include_directories(my_project_test PRIVATE ${CMAKE_SOURCE_DIR}/third_party/doctest)

3. 保持测试main.cpp的正确写法

test目录下的test_main.cpp仅需保留doctest的main实现,无需额外逻辑:

// test/test_main.cpp
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest/doctest.h>

验证效果

  • 编译生产版本:无DOCTEST_INCLUDE_TESTS宏,生产代码中的测试被预编译排除,原main函数正常运行,生产二进制无测试冗余。
  • 编译测试版本:激活宏后,生产代码中的测试与test目录的测试被统一收集,运行测试二进制即可执行所有用例。

内容的提问来源于stack exchange,提问作者Vinícius Ferrão

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:32:31