dag*_*rym 6 c++ linux unit-testing cppunit
我正在使用CppUnit设置一堆单元测试,但我遇到的问题是没有运行任何测试.该项目分为几个小型库,我计划以相同的方式划分单元测试类,然后将它们全部链接到一个测试程序中.问题是,然后测试类在他们自己的库中,他们没有链接到主测试程序,除非我明确地调用它们,即我必须放入
runner.addTest( TestClass::suite() );
单独为每个测试类,不能使用TestFactoryRegistry的makeTests()方法来获取测试列表.如果我只是在顶层目录中一起编译它们,那么makeTests()方法可以正常工作,但如果我能帮助它,我不希望将所有测试类放在一个位置.
CppUnit文档提供了以下一点提示
使用Helper宏时链接问题?
当您创建项目并编写其单元测试套件时,通过使用所谓的帮助程序宏可以更轻松地完成工作:CPPUNIT_TEST_SUITE_NAMED_REGISTRATION,CPPUNIT_REGISTRY_ADD和CPPUNIT_REGISTRY_ADD_TO_DEFAULT.问题是,如果你在TestFixture类的源代码文件中使用这些宏(比如说MyTest作为例子),如果你使用像这样的一行
Run Code Online (Sandbox Code Playgroud)runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest());
在main.cpp文件的main()函数中,根本就没有测试运行!
原因很简单,如果main.cpp中没有未定义的符号,链接阶段(构建过程的一个步骤)不会在最终的可执行文件中插入目标文件(.obj或.o文件).
这样,包含AutoRegister静态变量实例化的目标代码不是最终可执行文件的一部分,并且无法在main()函数中将自己插入到运行程序中.
您必须在main.cpp中创建一个未定义的符号,以便mytest.o文件与main.o集成到最终的可执行文件中.
米歇尔·诺拉德犯下的伎俩
但是并没有说如何使这项工作,我只是足够密集,不能自己弄明白或在网上找到一个例子.
现在我可以为每个库做一个单独的可执行测试,最后我可能会这样做,但我想尝试让它先工作,所以我只需要运行一个测试程序来测试整个事情.有关如何使其工作的任何想法/示例?
通过向 main 添加一个未定义的符号,他只是意味着创建任何随机的外部符号来强制链接器搜索包含测试代码的外部库。
例如,假设有两个测试库 fred 和 barney,在 fredTestLib.cpp 中您只需添加以下行:
int fredDummyInt = 0; // declare a unique symbol for the linker to resolve
Run Code Online (Sandbox Code Playgroud)
在 barneyTestLib.cpp 中,您将添加类似的行:
int barneyDummyInt = 0; // a different unique symbol for the linker to resolve
Run Code Online (Sandbox Code Playgroud)
您可以在不同的步骤中单独编译每个库。然后在主测试程序中,强制链接器解析它们。因此,将这些行添加到 main.cpp 中:
extern int fredDummyInt;
extern int barneyDummyInt;
...
main () {
...
fredDummyInt++; // give the linker some symbols to resolve
barneyDummyInt++;
...
Run Code Online (Sandbox Code Playgroud)
这个想法(根据上面技巧的作者所说)是因为链接器已经在 fredTest.lib 中搜索 fredDummyInt,所以它也会找到并解析您自动注册的测试。
注意:我还没有尝试过这个方法是否有效!我只是回答你关于外部的问题。
另一种需要考虑的方法是在 DLL 中创建测试,并使用 LoadLibrary() 显式地将它们引入运行。对于过度杀戮,如果您使用 MfcUi::TestRunner,您可能可以构建一个小的下拉 GUI 东西,让您选择要加载的库,加载它,然后显示要在该库中运行的测试,然后运行它们。