使用Boost.Test能否将单元测试拆分到不同源文件及报错排查
问题根因
出现多重定义错误是三个配置错误共同导致的:
- 每个测试源文件都定义了
BOOST_TEST_MODULE宏。这个宏会触发当前编译单元生成Boost.Test的主入口、全局配置对象、测试注册单例等全套框架实现,多文件同时定义就会在链接时出现多份重复实现。 - 混用了Boost.Test的两种使用模式。
test_config.h中引入的<boost/test/included/unit_test.hpp>是Header-only单文件模式专用头,会把全部框架实现直接插入每个包含它的编译单元;但Makefile中又额外链接了预编译库libboost_unit_test_framework,等于又引入了第三份重复实现。 - Makefile编译规则写法错误。生成目标文件的命令漏了
-c参数(不加该参数g++会直接尝试链接可执行文件,无法生成正确的.o文件),同时源文件和目标文件的顺序写反,自动化变量$<代表第一个依赖(即.cpp源文件),$@代表输出目标,原命令顺序完全颠倒。
Boost.Test原生支持多文件拆分测试用例,单文件能运行只是因为规避了多编译单元的重复定义问题,按以下方法修正即可正常拆分。
修正步骤
1. 调整测试文件宏定义
整个测试程序只能有一个编译单元定义BOOST_TEST_MODULE宏,其余测试用例文件不要定义该宏。
推荐单独新建主入口文件test_main.cpp:
// 唯一允许定义BOOST_TEST_MODULE的文件 #define BOOST_TEST_MODULE Fast_Test_Suite #include "../include/test_config.h"
修正原有两个测试文件,删除顶部的BOOST_TEST_MODULE定义:
test_size.cpp
#include "../include/test_config.h" BOOST_AUTO_TEST_CASE(test_repeats) { int n = 30; Repeats r = Repeats(n); BOOST_REQUIRE(r.rep == n); }
test_repeats.cpp
#include "../include/test_config.h" BOOST_AUTO_TEST_CASE(test_size) { int n = 20; int m = 30; Size sz = Size(n, m); BOOST_REQUIRE(sz.n == n && sz.m == m); }
2. 统一Boost.Test使用模式
两种模式二选一,不要混用:
- 选预编译链接模式(推荐多文件场景使用):修改
test_config.h,去掉头文件路径中的included/前缀,使用标准库头,保留Makefile中的-lboost_unit_test_framework链接参数:// test_config.h 修正后内容 #include <boost/test/unit_test.hpp> #include "../include/size.h" #include "../include/repeats.h" - 选Header-only模式:仅在
test_main.cpp中包含<boost/test/included/unit_test.hpp>,其余测试文件包含<boost/test/unit_test.hpp>,同时删除Makefile中的-lboost_unit_test_framework链接参数。
3. 修正Makefile规则
补全编译参数,调整文件顺序,把新增的test_main.cpp加入编译源列表,修正后示例:
FAST_HEADERS := $(wildcard Fast/**/*.h) # 加入test_main.cpp,排除业务代码的main.cpp FAST_TEST_SOURCES := $(filter-out Fast/src/main.cpp, $(wildcard Fast/src/*.cpp Fast/tests/*.cpp)) FAST_TEST_OBJECTS := ${FAST_TEST_SOURCES:.cpp=.o} fast_test: $(FAST_TEST_OBJECTS) g++ $(FAST_TEST_OBJECTS) -lboost_unit_test_framework -o fast_test ./fast_test # 加-c参数指定生成目标文件,修正源文件和目标文件顺序 %.o: %.cpp $(FAST_HEADERS) g++ -c $< -o $@
修正后重新执行make即可正常编译运行多文件拆分的测试用例。
内容的提问来源于stack exchange,提问作者Potatmen
相关产品推荐
相关产品推荐

