我有一个我用C ++创建的静态库,想用驱动程序代码测试它。
我注意到我的一位教授喜欢使用python进行测试,但他只是使用随机测试参数执行程序(在这种情况下不是库,而是可执行文件)。
我想采用这种方法,但我意识到这是一个库而且没有主要功能;这意味着我应该创建一个Driver.cpp类,或者使用SWIG或boost python将库包装到python中。
我打算做后者,因为它似乎更有趣,但从逻辑上讲,我觉得尝试将库包装到另一种语言只是为了测试它而不是测试它时会有更多的错误它的母语。
用不同的语言测试程序是否是现实世界中公认的做法,还是这种不好的做法?
答案 0 :(得分:26)
我说最好测试一下您的用户将会接触到的API。其他测试也很好,但这是最重要的方面。
如果您的用户要编写链接到您的库的C / C ++代码,那么以相同的方式使用您的库进行测试会很好。
如果您要发布Python包装器(为什么不呢?)那么您应该进行Python测试。
当然,这也有一个方便的方面。在Python中编写测试可能更容易,并且您可能有时间限制使其更具吸引力等等。
我想我所说的是:测试与被测代码的语言不同,没有任何内在错误(例如,测试REST API是完全正常的,例如),但要确保至少对面向公众的API进行测试。
除此之外,还有术语:
我不认为你所描述的测试类型是"单元测试"按照通常意义上讲。可能"功能测试"会更准确。
单元测试通常测试一个非常小的组件 - 例如函数调用 - 可能是一个更大的功能。像这样的单元测试通常是"白盒"测试,以便您可以看到代码的内部工作原理。
从用户的角度测试某些内容(例如您的教授的命令行测试)是"黑盒"测试,并在这些例子中处于更具功能性的水平,而不是"单位"水平。
我确信很多人可能不同意这一点,但这并不是一套严格定义的术语。
答案 1 :(得分:8)
要记住的一些事项:
如果您在编写代码时编写测试,那么,无论如何,请使用最适合的语言来为您提供快速反馈。这可以实现快速的测试代码循环(并且也很有趣)。的 BUT 强>
始终使用 使用者 的语言编写精心编写的测试。您的客户/消费者如何调用您的功能?他们会用什么语言?使用相同的语言可以在生命周期的后期最小化集成问题。
答案 2 :(得分:5)
这实际上取决于你试图测试的是什么。使用与您正在测试的代码相同的语言编写单元测试几乎总是有意义的,这样您就可以构建测试中的对象或调用测试中的函数,这两者都可以用同一种语言轻松完成,并验证他们正常工作。但是,有些情况下使用不同的语言是有意义的,即:
集成测试,可以同时运行多个不同的组件或应用程序。
验证无法在语言中测试的编译或解释失败的测试,因为您正在验证语言级别是否发生错误。
#1的示例可能是启动多个彼此连接的不同服务器的程序,向服务器发出请求并验证这些响应。或者,作为一个更简单的示例,一个程序只是将正在测试的应用程序作为子进程分叉,并验证它是否为给定的输入生成了预期的输出。
#2的示例可能是一个程序,用于验证某个C ++代码是否会产生静态断言失败,或者如果有人试图使用它,则故意禁止的特定模板实例化将导致编译失败。
要回答您的大问题,用不同的语言编写测试本身并不错。无论是什么使得测试更方便编写,更容易理解,对实现更改更加健壮,对回归更敏感,以及更好地定义良好测试的任何一个属性将是一个很好的理由,以一种方式编写测试。如果这意味着用另一种语言编写测试,那就去吧。话虽这么说,小单元测试通常需要能够直接调用被测项目,在大多数情况下,这意味着用与被测组件相同的语言编写单元测试。
答案 3 :(得分:4)
为什么不呢,这是一个很棒的主意,因为你真的明白你正在测试这个单位就像一个黑盒子。
当然可能存在技术问题,如果您需要模拟被测单元的某些部分,那么在另一种语言中可能会很困难。
这是集成测试的常见做法,但我已经看到很多程序来自外部工具,例如来自selenium的网站或来自黄瓜的应用程序。这两者都可以被认为与自定义python脚本相同。
如果您认为集成测试和单元测试之间的区别在于任何给定时间内测试的事物的数量,那么您不应该这样做的唯一原因是工具支持。
答案 4 :(得分:3)
我想说这取决于你实际想要测试的内容。对于真正的单元测试,我认为最好使用相同的语言或至少是二进制兼容的语言进行测试(即使用Java
测试Groovy
- 我在这种情况下Spock
使用Groovy
来对我的Java
代码进行单元测试,因为我可以将Java
与Groovy
混合在一起,但如果您正在测试结果,那么我认为切换语言是公平的。
例如,我在Perl
通过nose
运行Python
应用程序时,在给定一组特定数据时测试了预期结果。这是有效的,因为我本身不是单元测试Perl代码,而是Perl代码的结果。
在这种情况下,要对作为应用程序一部分的实际Perl
函数进行单元测试,我将使用基于Perl
的测试框架,例如Test::More
。