使用CppUnit链接测试库

时间:2009-06-19 03:14:26

标签: 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   例如),如果你使用像这样的行   这一个

runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest()
     

);

     

在文件中的main()函数中   main.cpp,没有测试运行   一点都没有!

     

原因很简单就是链接   阶段,构建的一个步骤   进程,不要插入对象   最后的文件(.obj或.o文件)   如果没有未定义,则可执行   main.cpp中的符号。

     

那样,对象代码当中   包含AutoRegister静态   变量实例化不是其中的一部分   最终的可执行文件,但不能   将自己插入跑步者中   main()函数。

     

您必须创建一个未定义的符号   在main.cpp中,以便mytest.o文件   与main.o集成到   最终的可执行文件。

     

Michel Nolard犯下的伎俩

但是没有说明如何完成这项工作而且我只是足够密集,不能自己解决或在网上找到一个例子。

现在我可以为每个库做一个单独的可执行测试,最后我可能会这样做,但我想尝试先让这个工作,所以我只需要一个测试程序来测试整个事情。有关如何使其发挥作用的任何想法/示例?

3 个答案:

答案 0 :(得分:1)

通过向main添加一个未定义的符号,他只是意味着创建任何随机的外部符号来强制链接器搜索包含测试代码的外部库。

例如,假设有两个测试库fred和barney,在fredTestLib.cpp中你只需要添加这一行:

int fredDummyInt = 0; // declare a unique symbol for the linker to resolve

在barneyTestLib.cpp中,你会添加一个类似的行:

int barneyDummyInt = 0; // a different unique symbol for the linker to resolve

您可以在不同的步骤中单独编译每个库。在主测试程序中,然后强制链接器解析它们。所以将这些行添加到main.cpp:

extern int fredDummyInt;
extern int barneyDummyInt;
...
main () {
    ...
    fredDummyInt++; // give the linker some symbols to resolve
    barneyDummyInt++;
    ...

这个想法(根据上面诀窍的作者所说)是因为链接器已经在fredTest.lib中搜索fredDummyInt,它也会找到并解决你自动注册的测试。

注意:我没有试过这个看它是否有效!我只是回答你关于外部的问题。

另一种需要考虑的方法是在DLL中创建测试,并使用LoadLibrary()显式地将它们运行起来。对于矫枉过正,如果您使用MfcUi :: TestRunner,您可能会构建一个小的下拉式GUI,让您选择要加载的库,加载它,然后显示要在该库中运行的测试,然后运行它们。 / p>

答案 1 :(得分:0)

这个问题的解决方案很简单,就像之前的状态一样(但可能不是很优雅)。 对于位于外部库中的每个TestFixture,您必须在主模块中添加以下两行代码

#include <CppUnitTestFixtureExample.h>
CppUnitTestFixtureExample Test1;

它创建一个未使用的未使用的虚拟变量,它只是强制链接器链接测试夹具。现在,位于主模块中的测试运行器能够运行测试。

答案 2 :(得分:0)

我意识到这篇文章现在已经很老了,但对于遇到它的其他人来说: 解决此问题的一种方法是在代码中引用,但是指示(强制)链接器将整个静态库包含在二进制文件中。详细信息区域可从gcc&amp; ld手册页,这篇文章也涵盖了它: How to force gcc to link unreferenced, static C++ objects from a library

Per ld的手册页,重要的是要考虑明确关闭选项(也在上面的一个示例中显示)。