如何在大规模C++项目中实现单元测试?

43

我强烈相信在构建大型多平台应用程序时,使用单元测试是必要的。我们目前计划将我们的单元测试放置在一个独立的项目中,这样可以保持我们代码库的整洁。但我认为这会将测试代码与单元实现分开。你认为这种方式怎么样?是否有像 JUnit 一样适用于 C++ 应用程序的工具?


刚有一个非常类似的问题被问到了。看看 CppUnitCppUnitLite 和 “与遗留代码有效工作”(都是 Michael Feathers 著)的内容。 - Seb Rose
9个回答

23

1
与JUnit不同,更适合C ++的是CATCH - Martin Moene

13

这是一个合理的方法。

我使用UnitTest++Boost.Test都取得了非常好的结果。

我看过CppUnit,但对我来说,它更像是JUnit的翻译,而不是针对C++的东西。

更新:现在我更喜欢使用Catch。我发现它非常有效且易于使用。


4
doctest 是我对 Catch 的重新实现,非常注重编译速度 - 请查看 FAQ 以了解它们之间的不同之处。 - onqtam

3
你应该将基础代码分离到一个共享(动态)库中,然后为该库编写大部分单元测试。
两年前(2008年),我参与了由Linux基金会部署的大型LSB基础设施项目。该项目的目标之一是为Linux核心库的40,000个函数编写单元测试。在这个项目的背景下,我们创建了AZOV technology和基本工具API Sanity Autotest,以便自动生成所有测试。您可以尝试使用此工具为您的基础库生成单元测试。

2

我认为你的单元测试方法是正确的,并且这是提高产品可靠性的绝佳方案。

然而,当将应用程序转换到不同平台甚至不同操作系统时,单元测试并不能解决所有问题。原因在于单元测试通过揭示应用程序中的错误来进行测试。它只是简单地将尽可能多的输入投入系统,并等待另一端的结果。就像让猴子不断地敲击键盘并观察结果(Beta测试人员)。

要进一步推进单元测试,您需要关注应用程序的内部设计。我发现最好的方法是使用称为“合约编程”或“按合约设计”的设计模式或设计流程。对于将可靠性构建到核心设计中非常有帮助的另一本书是:

Debugging the Development Process: Practical Strategies for Staying Focused, Hitting Ship Dates, and Building Solid Teams.

在我们的开发团队中,我们非常仔细地研究了我们认为是程序员错误、开发者错误和设计错误,以及如何通过单元测试和按照调试开发过程的建议来构建软件包的可靠性。


2
我使用UnitTest++。测试在一个单独的项目中,但实际测试与实际代码交织在一起。它们存在于受测试部分下的文件夹中。 例如:
MyProject\src\ <- 实际应用程序的源码
MyProject\src\tests <- 测试的源码
如果您有嵌套的文件夹(谁没有呢),那么它们也会有自己的 \tests 子目录。

我们也是这样做的,我们的构建系统会自动从任何单元测试源文件夹下找到的代码构建测试EXE。 - Greg Whitfield

1

Cppunit是C++应用程序的直接等效物,类似于Junit。 http://cppunit.sourceforge.net/cppunit-wiki

个人而言,我在不同的项目中创建了单元测试,并创建了一个单独的构建配置,该配置构建了所有单元测试和相关源代码。在某些情况下,我想测试类的私有成员函数,因此将Test类设置为要测试的对象的友元类,但通过预处理器声明在“非测试”配置中隐藏了友元声明。

最终,我进行了这些编码体操,因为我正在将测试集成到遗留代码中。但是,如果您从开始就旨在进行单元测试,则更好的设计可能会更简单。


1

你可以为源代码树中的每个库创建一个单元测试项目,放在该库的子目录中。这样,你就会得到每个库的测试驱动程序应用程序,从而更容易地运行单个测试套件。将它们放在子目录中可以保持你的代码库整洁,同时也使测试与代码保持接近。

可以轻松编写脚本来运行源代码树中的所有测试套件并收集结果。

我多年来一直使用定制版本的原始CppUnit,并取得了巨大的成功,但现在有其他选择。GoogleTest看起来很有趣。


1

CxxTest 是一个轻量级、易于使用的跨平台 JUnit/CppUnit/xUnit 框架,非常适合 C++。我们发现它非常容易添加和开发测试。

Aeryn 是另一个值得关注的 C++ 测试框架。


1

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