参数化测试-您何时以及为何使用它们?


15

最近在工作中,我们对参数化测试存在一些意见分歧。通常,我们使用TDD样式(或至少尝试使用),因此我了解该方法的好处。但是,我很难看到参数化测试带来的收益。作为参考,我们致力于一项服务及其通过RESTful接口公开的库。

到目前为止,我所看到的是至少在Eclipse中使用JUnit的测试:

  • 缺少详细信息-测试失败时,很难查看导致测试失败的参数
  • 通常创建起来很复杂
  • 倾向于在编写代码后创建-严格来说,这并不是缺点,但是人们在开始编写一段代码时是否着眼于参数化测试?

如果有人提供了一些示例,说明它们在哪些地方真正有用,甚至有任何很好的使用它们的提示,那就太棒了。我想确保我不仅固执己见,因为我个人不选择使用它们,而是查看它们是否属于我们应该考虑成为测试武器库的一部分。


1
问题不在于想法,而在于笨拙的库。在C#中,当您说MbUnit时,语法会更友好。是的,这是一个好主意。添加您自己的代码以使此过程更轻松-从文件中读取内容-不管用什么。还要看看MsTest是如何处理的。
Job

我们(Square)写了Burst来解决这些问题Parameterized。通常,它减少了样板,并且很清楚测试失败的地方。
Daniel Lubarov 2014年

Answers:


4

测试任何软件的问题在于,复杂性很快就消失了。事实是,您无法测试传递给方法的参数的所有可能组合。 Phadke提倡一种“实验设计(DOE)”方法,该方法可以生成可能需要测试的参数值列表。

这个想法是,即使您没有进行详尽的测试,大多数缺陷也会导致出现“故障区域”,而不是孤立的点故障。DOE方法Phadke提倡使用正交阵列对参数空间进行足够精细的采样,以击中所有可能的故障区域。

孤立的故障可能不会被识别,但是这些故障通常少于故障区域。

DOE方法为您提供了一种选择参数值以进行变化的系统方法。


提供的链接已断开。
乔什·古斯特

1
@JoshGust使用Google可以轻松修复。感谢您的注意。
彼得·K,

4

它们对于确保您的代码不仅处理快乐路径,而且还处理边缘情况非常有用。在知道您的代码可以使用普通变量后,对测试用例进行参数设置,并确保null和0,空字符串,大数字,长字符串,奇怪的Unicode字符等也可以正常工作。


2

至少在JUnit 4.8中,至少有两种类型的参数化测试。这些是:参数化测试(@RunWith(Parameterized.class)需要数据源的),该数据源生成/读取预定义的参数配置;以及理论(@RunWith(Theories.class)),对于每种参数类型,给定一个或多个可能的输入集,它们就可以执行给定方法的规范。看起来更像这样:

  • 指定一些可能的值(@DataPoints为字符串参数(例如null,空字符串,非空字符串,很长的字符串))
  • @DataPoints为Animal类参数指定一些可能的值()nullDog例如,Cat实例,Bird实例))
  • 准备@Theory接受一个String参数和一个Animal参数。它将以可能的参数值的每种可能的组合执行(在给定的示例中为4x4 = 16个组合,包括(nullnull))
  • 如果被测方法不能接受某种组合,请使用Assume.assumeThat静态导入来过滤无效组合(例如,当您要检查非空字符串的方法行为时,第一行将是“假定不为空”

如前所述-测试每种方法的每种可能组合都是没有意义的(它会爆炸测试集,想象一下用5个参数测试一个方法,每个参数只有5个可能的值:5 ** 5->超过3000次测试运行!),但是对于关键任务方法(例如API方法),我建议您这样做,只是为了安全起见...


1

通用示例:

  • 具有字符串参数的方法。使用参数化测试来测试不同的输入及其预期输出。具有成对的列表(输入,预期)比为每对编写一个TC更实用。

  • 将相同的方案应用于不同的参数。我们有与工作的场景Animal对象和有很多子类,如中DogCatBird。创建可用动物的列表,然后对它们进行测试。

Web服务的具体:

  • 从上面的字符串参数示例。测试使用相同类型但值不同的不同参数会发生什么。

0

当您要测试各种输入时,参数化测试非常适合具有简单输入的测试功能/功能。

它们不适用于测试不同的功能和复杂的输入。它们不应用作编写较少代码的便利结构。


1
为什么应该使用参数来减少编写代码的便利?提供大量(ish)测试用例的详尽清单并没有太大的优点。
乔纳森·尤尼斯

1
与其他5个答案相比,您的答案如何提供更多信息?
亚当·祖克曼

-2

我以TDD式方式使用大量参数化测试的一种情况是编写解析器-我可以从输入和预期输出的列表开始,然后编写代码,使其通过所有测试用例。

但是我看到了一些参数化测试的恐怖。不,弗吉尼亚,您的测试套件不需要它自己的单元测试。


1
理想情况下,参数化测试的形式应为“实际输出中的项目(n)是否与预期输出中的项目(n)相匹配”或类似形式,在这种情况下,无需进行测试。但是对于更复杂的事情,我宁愿看到一个干净的参数化测试,也要使用自己的测试用例,而不是通常挥舞着的“我的(测试)代码显然是正确的”。如果那是真的,那么您根本就不会编写测试用例。显然,可能会过于复杂,而且我并不认为没有界限,但是我认为在某些情况下,测试是个好主意。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.