可执行项目的单元测试

15
也许我没有正确思考这个问题。我正在开始我的第二个使用单元测试的项目。我的第一个项目是自己编写的,对于这个项目,我想试用Boost::test。
我的问题是,对于编译为可执行文件的项目,进行单元测试的适当流程是什么?似乎所有我看到的内容都是针对库和依赖项的。我希望我的可执行文件项目能够进行单元测试,但我不想在二进制文件中出现大量的单元测试函数,也不想进行...
#ifdef _DEBUG
    BOOST_AUTO_TEST_CASE( my_func )
    {
    }
#endif

我在所有测试中使用了around。

我考虑创建一个单独的项目用于单元测试,但这对可执行文件来说并不真正适用...除非我想要做一些花哨的预构建操作,将其他项目复制到测试项目中。

有什么想法或主意吗?


你应该更新你的问题以避免误解 - 我似乎不是唯一一个这样认为的人。 - Georg Fritzsche
5个回答

9

该项目可以编译为一个库,然后这个库可以被链接到两个不同的可执行文件中:一个是将要发布的“项目”,另一个是单元测试。

现在问题似乎源于你使用的集成开发环境(IDE),请问你使用的是哪种IDE?它能否为一个项目创建两个二进制文件?


1
我选择了这个解决方案,但要确保如果你这样做,你的编译器知道链接库中的所有对象。在Visual Studio中,您可以在链接器选项中设置“使用库依赖项输入”,在gcc中,我相信选项是-z allextract或类似的东西。 - Charles

6
我使用 cppunit 来测试我的可执行文件,它在一个额外的项目中链接到从可执行文件代码生成的 *.obj 文件。这样,您就没有任何测试逻辑在原始代码库中,并且可以为测试编写单独的控制台或 Windows 应用程序。
祝好 Holger

你可以像在使用库文件时一样,将所需的*.obj文件添加到链接器输入文件中,至少在Visual Studio中是这样。 - codencandy

3
创建一个单独的项目,测试代码的不同“单元”是否按预期运行,无论是构建调试还是非调试版本(由于代码差异,某些问题甚至在调试版本中都不会出现)。将其构建为二进制文件并运行以查看更改是否破坏了任何东西 - 通常设置为自动后置构建操作。
如果您想从外部测试应用程序,则可能可以使用一些测试框架,具体取决于应用程序的领域/框架等。但是,Boost.Test和所有其他单元测试框架都不适用于测试可执行文件。

感谢您的快速回复。我知道单元测试在库中非常有效,但我想对可执行文件进行单元测试,因此我需要实际定义我的main()函数。这在我的单元测试解决方案中不是问题,但在Boost::test中却是个问题:( - Charles
提供一个最小的主函数来初始化单元测试不应该太麻烦。但是,可以在这里查看自动初始化:http://www.boost.org/doc/libs/1_41_0/libs/test/doc/html/utf/user-guide/initialization.html#utf.user-guide.initialization.auto-generation - Georg Fritzsche
如果有帮助的话,这里有一些有用的例子:http://github.com/jsankey/boost.test-examples/ - Georg Fritzsche
是的,我已经让boost::test“工作”了;p。不得不花一些时间研究文档,以了解如何设置所有内容。如果我不定义一个main函数,我的简单测试就可以很好地工作。但是,如果我尝试使用BOOST_TEST_NO_MAIN并从我的主函数调用unit_test_main,则链接失败,因为静态库定义了main函数。我正在尝试重新构建静态库,甚至是动态库,但这仍然会给我留下一个包含大量测试定义的可执行文件。 - Charles
啊,你在库构建期间是否定义了 BOOST_TEST_NO_MAIN - Georg Fritzsche

2
可对可执行文件进行单元测试,这是个好主意。但要认识到,与单元测试代码不同,这是完全不同的事情。一旦你有了一个可执行文件,就没有C++或Boost了。它只是一个程序。您需要能够以不同的机制运行它并分析/控制输入:
输入:
- 参数 - stdin - 环境变量(也许) - 配置文件(也许)
输出:
- 返回值 - stdout - 输出文件(也许)
最简单的方法可能是在shell中运行它。bash将在Linux环境中奏效(将管道传输到/从文件,对输出运行sed/awk/grep以分析正确性)。您可以使用Perl或Python及其各自的单元测试框架,但必须在其他函数中包装对程序的调用:两种语言都支持来自子进程的管道,Python使用subprocess模块,Perl使用其标准文件打开机制。
无论您做什么,都不要尝试从C ++对整个可执行文件进行单元测试。

我并不是真的要测试已构建的可执行文件,我的意思是我的项目编译为一个exe而不是一个库。大多数单元测试框架都是为库设计的,因此才会有这种困惑和问题。 - Charles

1

您可以从单元测试项目中包含必要的 .cpp 文件并对其进行测试。

就像我所做的那样:

Tests\GameServer\PVESettingsTest.cpp:

#include "../../sources/GameServer/PVESettings.cpp"

一切正常...


这种方法会使编译时间加倍。在你的例子中,PVESettings.cpp 被编译了两次:一次是为原始项目,另一次是为单元测试。对于小型项目来说可能微不足道,但随着项目的增长,这将变得非常痛苦。 - nnovich-OK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接