【问题标题】:Unit testing an executable project对可执行项目进行单元测试
【发布时间】:2010-12-26 16:17:45
【问题描述】:

也许我没有正确考虑这个问题。 我正在使用单元测试开始我的第二个项目。我的第一个项目是我自己推出的,对于这个项目,我正在尝试 Boost::test。

我的问题是,将单元测试项目编译成可执行文件的正确程序是什么?似乎我看到的所有内容都是针对库和依赖项的。我希望我的 exe 项目进行单元测试,但我不希望在二进制文件中浮动一堆单元测试函数,我也不想这样做

#ifdef _DEBUG
    BOOST_AUTO_TEST_CASE( my_func )
    {
    }
#endif

围绕我所有的测试。

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

有什么想法或想法吗?

【问题讨论】:

  • 您可能应该更新您的问题以避免误解 - 我似乎不是唯一一个。

标签: c++ unit-testing boost


【解决方案1】:

这个想法是创建一个单独的项目,您可以在其中测试单独的单元代码以获得预期的行为,无论是否构建调试(有些问题甚至不会出现在调试构建中,因为代码差异)。
您将其构建为二进制文件并运行以查看您的更改是否没有破坏任何内容 - 通常它甚至设置为自动构建后操作。

如果您想从外部测试您的应用程序 - 您可能可以使用一些测试框架,具体取决于区域/框架/等。应用程序的...但是 Boost.Test 和所有其他单元测试框架不适用于测试可执行文件。

【讨论】:

  • 感谢您的快速回复。我知道单元测试与库配合得很好,但我想对我的可执行文件进行单元测试,所以我需要实际定义我的 main() 函数。这不是我的单元测试解决方案的问题,而是 Boost::test 的问题:(
  • 提供一个最小的 main 来初始化单元测试应该不会太麻烦。请参阅此处进行自动初始化:boost.org/doc/libs/1_41_0/libs/test/doc/html/utf/user-guide/…
  • 如果有帮助,这里有一些有用的例子:github.com/jsankey/boost.test-examples
  • 是的,我得到了 boost::test 'working' ;p 必须研究文档一段时间才能了解如何设置所有内容。如果我不定义一个主要的,我的几个简单的测试效果很好。但是我尝试使用 BOOST_TEST_NO_MAIN 并从我的 main 函数调用 unit_test_main 并且它无法链接,因为静态库定义了 main。我现在正在尝试重建静态库,甚至是动态库,但这仍然给我留下了一个包含一堆测试定义的 exe。
  • 啊,你在构建库的时候也定义了BOOST_TEST_NO_MAIN吗?
【解决方案2】:

对可执行文件进行单元测试可能是个好主意 - 但要意识到它与单元测试代码完全不同。一旦有了可执行文件,就不再有 C++ 或 Boost。这只是一个程序。您需要能够运行它并以不同的机制分析/控制您的输入:

输入:

  • 参数
  • stdin
  • 环境变量(可能)
  • 配置文件(可能)

输出:

  • 返回值
  • stdout
  • 输出文件(可能)

在 shell 中运行它可能是最容易的。 bash 将在 Linux 环境中创造奇迹(管道到/从文件,在输出上运行 sed/awk/grep 以分析正确性)。您可以使用 Perl 或 Python 以及它们各自的单元测试框架,但需要注意的是您必须将程序的调用包装在其他一些函数中:两种语言都支持来自子进程的管道概念,python 带有 subprocess 模块和 Perl 的标准文件打开机制。

无论你做什么,你确实想尝试从 C++ 对整个可执行文件进行单元测试。

【讨论】:

  • 好吧,我并不是真的要测试构建的可执行文件,我的意思是我的项目编译为 exe,而不是库。大多数单元测试框架都是为库设计的,因此存在混淆和问题。
【解决方案3】:

项目可以编译为一个库,并且这个库可能静态链接在两个单独的可执行文件中:将交付的“项目”和单元测试。

现在问题似乎源于您的 IDE,它是哪一个?它是否允许为一个项目创建两个二进制文件?

【讨论】:

  • 我选择了这个解决方案,但要确保如果你这样做,你的编译器知道链接库中的所有对象。在 Visual Studio 中,您在链接器选项中设置使用库依赖输入,在 gcc 中我相信该选项是 -z allextract 或其他东西
【解决方案4】:

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

干杯 霍尔格

【讨论】:

  • 您可以像使用 lib 一样将所需的 *.obj 文件添加到链接器输入文件中,至少在 Visual Studio 中是这样。
【解决方案5】:

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

和我一样:

Tests\GameServer\PVESettingsTest.cpp:

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

一切正常...

【讨论】:

  • 此方法使编译时间加倍。在您的示例中,PVESettings.cpp 被编译了两次:用于原始项目和单元测试。对于小型项目来说可能微不足道,但随着项目的发展会变得很痛苦。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
相关资源
最近更新 更多