我正在研究一个C ++库,其中包括读取配置文件的功能。我想为此添加测试。到目前为止,这导致我创建了许多有效和无效的配置文件,每个配置文件只有几行来测试一个特定的功能。但它现在变得非常笨拙,因为有太多文件,还有许多小型C ++测试应用程序。不知怎的,这对我来说似乎不对:-)所以你有提示如何组织所有这些测试,测试应用程序和测试数据吗?
注意:库的公共API本身不易测试(它需要配置文件作为参数)。实际读取和解释配置值的多汁,容易出错的方法是私有的,所以我没有看到直接测试它们的方法?
那么:你会坚持对真实文件进行测试吗?如果是这样,您将如何组织所有这些文件和应用程序,以便它们仍然可维护?
答案 0 :(得分:5)
也许库可以接受某种流输入,所以你可以传入一个类似字符串的对象并避免所有的输入文件?或者根据配置类型,您可以直接提供“get / setAttribute()”函数,公开,调整参数。如果这不是一个真正的设计目标,那就别担心了。在某些地方,数据驱动的单元测试是不受欢迎的,但它肯定比没有好!我可能会像这样列出代码:
project/
src/
tests/
test1/
input/
test2
input/
在每个testN目录中,您将有一个与输入目录中的配置文件关联的cpp文件。
然后,假设您正在使用xUnit样式的测试库(cppunit,googletest,unittest++或其他),您可以将各种testXXX()函数添加到单个类中测试相关的功能组。通过这种方式,您可以通过将至少一些测试组合在一起来减少部分很少的程序问题。
唯一的问题是,如果库期望配置文件被调用特定的东西,或者在特定的地方。情况应该不是这样,但如果必须通过将测试文件复制到预期位置来解决这个问题。
不要担心大量的测试会使你的项目混乱,如果它们隐藏在测试目录中,那么它们就不会打扰任何人。
答案 1 :(得分:1)
第1部分。
正如理查德建议的那样,我会看一下CPPUnit测试框架。这将在一定程度上推动测试框架的位置。
根据Richard的示例,您的测试可以位于高级别的并行目录中,也可以位于与您要测试的区域平行的测试子目录或测试目录中。
无论哪种方式,请在整个项目的目录结构中保持一致! 特别是,如果测试包含在单个高级目录中。
没有什么比在以下位置维护源代码的心理映射更糟糕了:
/project/src/component_a/piece_2/this_bit
并将测试放在某处,例如:
/project/test/the_first_components/connection_tests/test_a
我参与了有人这样做的项目!
浪费了多少件湿器! 8-O谈论违反亚历山大的无名品质概念。
更好的办法是让你的测试始终如一地位于w.r.t.被测源代码的位置:
/project/test/component_a/piece_2/this_bit/test_a
第2部分
对于API配置文件,在每个本地测试区域中制作参考配置的本地副本,作为测试环境的一部分。在执行测试之前运行的设置。不要在整个测试树中撒上配置(或数据)的副本。
HTH。
欢呼声,
罗布
BTW真的很高兴看到你在设置时问这个问题!
答案 2 :(得分:0)
在我做过的一些测试中,我实际上已经使用测试代码编写配置文件,然后在测试使用该文件后删除它们。它在某种程度上填写了代码,我不知道它是不是很好的做法,但它确实有效。如果您碰巧使用boost,那么它的文件系统模块对于创建目录,导航目录和删除文件非常有用。
答案 3 :(得分:0)
我同意@Richard Quirk所说的内容,但您也可能希望让您的测试套件类成为您正在测试的类的朋友并测试其私有函数。
答案 4 :(得分:0)
对于这样的事情,我总是有一个小的实用程序类,它将一个配置加载到一个内存缓冲区,然后从那里它被送入实际的配置类。这意味着真正的来源并不重要 - 它可以是文件或数据库。对于单元测试,它在std :: string中进行硬编码,然后传递给类进行测试。您可以轻松地模拟currup!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
答案 5 :(得分:0)
假设您可以控制库的设计,我希望您能够重构,以便将实际文件读取的关注点与将其解释为配置文件分开:
现在要测试FileReader,您需要非常少量的实际文件(空,二进制,纯文本等),而对于ConfigFileInterpreter,您将使用FileReader类的存根来返回要读取的输入流。现在,您可以将所有各种配置情况准备为字符串,而不必阅读这么多文件。
答案 6 :(得分:0)
您将找不到比CppUnit更差的单元测试框架。说真的,任何推荐CppUnit的人都没有真正看过任何竞争框架。
所以,是的,去单元测试franework,但不要使用CppUnit。