单元测试-如何组织C++测试应用程序和相关文件

unit testing - How to organize C++ test apps and related files?

本文关键字:文件 应用程序 测试 何组织 C++ 单元测试      更新时间:2023-10-16

我正在开发一个C++库,它(以及其他东西)具有读取配置文件的功能;我想为此添加测试。到目前为止,这让我创建了许多有效和无效的配置文件,每个文件只有几行测试一个特定的功能。但它现在变得非常笨拙,因为有这么多文件,还有很多小的C++测试应用程序。不知怎的,这在我看来是错误的:-)那么你有关于如何组织所有这些测试、测试应用程序和测试数据的提示吗?

注意:库的公共API本身不容易测试(它需要一个配置文件作为参数)。实际读取和解释配置值的有趣、容易出错的方法是私有的,所以我看不到直接测试它们的方法?

所以:你会坚持针对真实文件进行测试吗;如果是这样的话,你将如何组织所有这些文件和应用程序,使它们仍然可以维护?

也许库可以接受某种流输入,这样你就可以传入一个类似字符串的对象,并避免所有的输入文件?或者,根据配置的类型,您可以提供"get/setAttribute()"函数来直接、公开地篡改参数。如果这不是一个真正的设计目标,那也没关系。数据驱动的单元测试在某些地方是不受欢迎的,但它绝对比什么都没有好!我可能会这样布置代码:

  project/
          src/
          tests/
                test1/
                      input/
                test2
                      input/

在每个testN目录中,都会有一个与输入目录中的配置文件关联的cpp文件。

然后,假设您使用的是xUnit风格的测试库(cppunit、googletest、unittest++或其他),您可以将各种testXXX()函数添加到单个类中,以测试相关的功能组。这样,您就可以通过将至少一些测试分组在一起来解决许多小程序的部分问题。

唯一的问题是,如果库希望配置文件被调用特定的东西,或者位于特定的位置。情况不应该是这样,但如果是这样,就必须通过将测试文件复制到预期位置来解决。

不要担心大量的测试会打乱你的项目,如果它们被藏在测试目录中,那么它们就不会打扰任何人。

第1部分。

正如Richard所建议的,我将研究一下CPPUnit测试框架。这将在一定程度上推动测试框架的定位。

根据Richard的例子,您的测试可以位于高级的并行目录中,也可以位于与要测试的区域并行的测试子目录或测试目录中。

无论哪种方式,请在整个项目的目录结构中保持一致特别是在测试包含在单个高级目录中的情况下。

没有什么比必须在以下位置维护源代码的心理映射更糟糕的了:

/project/src/component_a/piece_2/this_bit

并将测试定位在某个地方,例如:

/project/test/the_first_components/connection_tests/test_a

我参与过一些有人这样做的项目!

多么浪费湿货循环啊!8-O谈论违反亚历山大的"没有名字的质量"概念。

更好的方法是让你的测试始终位于测试中源代码的位置:

/project/test/component_a/piece_2/this_bit/test_a

第2部分

对于API配置文件,在每个本地测试区域中制作引用配置的本地副本,作为测试环境的一部分。在执行测试之前运行的安装程序。不要在测试树中到处散布配置(或数据)的副本。

HTH。

欢呼,

Rob

BTW真的很高兴看到你现在在设置时问这个问题!

在我所做的一些测试中,我实际上使用测试代码来编写配置文件,然后在测试使用该文件后将其删除。它在一定程度上填充了代码,我不知道这是否是一个好的实践,但它起了作用。如果您碰巧使用boost,那么它的文件系统模块对于创建目录、导航目录和删除文件非常有用。

我同意@Richard Quirk的说法,但你也可能想让你的测试套件类成为你正在测试的类的朋友,并测试它的私有函数。

对于这样的事情,我总是有一个小的实用程序类,它将把配置加载到内存缓冲区中,然后从那里它被馈送到实际的配置类中。这意味着真正的源并不重要——它可以是一个文件或数据库。对于单元测试,它是用std::字符串硬编码的,然后传递给类进行测试。你可以模拟咖喱!pte3d数据易于测试故障路径。

我使用UnitTest++。我把测试作为src树的一部分。因此:

solution/project1/src <-- source code
solution/project1/src/tests <-- unit test code 
solution/project2/src <-- source code
solution/project2/src/tests <-- unit test code 

假设您可以控制库的设计,我希望您能够进行重构,从而将实际文件读取的问题与将其解释为配置文件的问题分开:

  1. 类FileReader读取文件并产生输入流
  2. 类ConfigFileInterpreter验证/解释等输入流的内容

现在要测试FileReader,您需要非常少量的实际文件(空、二进制、纯文本等),对于ConfigFileInterpreter,您将使用FileReader类的存根,该存根返回要读取的输入流。现在,您可以将所有各种配置情况准备为字符串,并且不必读取那么多文件。

您不会发现比CppUnit更糟糕的单元测试框架。说真的,任何推荐CppUnit的人都没有真正看过任何竞争框架。

所以,是的,去做一个单元测试的franework,但不要使用CppUnit。