生成随机但静态的测试数据

时间:2014-03-17 16:15:43

标签: java testing

在设计测试用例时,我希望能够使用随机但静态的数据。

如果我使用非随机数据,那么我将使用代表我期望的数据的简单示例,而不是我在代码中防范的数据。例如,如果我的代码期望一个最大长度为15个字符的字符串,那么我宁愿指定这些约束并在这些约束中为我生成数据,而不是由于我的期望,可能会出现一些任意的例子。在更严格的约束条件下。

如果我使用非静态数据,那么我的测试将无法重复。使用每次运行测试时更改的字符串都是不错的,然后测试会偶尔失败。使用一致的字符串然后指定更多关于如何生成该字符串的约束(并且显然在我的代码中进行相同的检查),如果找到错误将会更好。

这是测试数据的好策略吗?

如果是这样,那么我就知道如何独立实现这两个目标。对于静态但非随机的数据,我只需输入任意数据,例如foo。对于随机但不是静态的东西,我只使用apache random utils,例如randomString(5)。我怎样才能得到两者?

请注意,当数据必须是唯一的时,通过某种方式指定两个生成的数据必须是不同的也是很方便的。随机性在大多数情况下都会这样做,但显然不能依赖于不可靠的测试!

TL; DR:如何在不随机生成数据的情况下指定我想要生成的数据类型?

3 个答案:

答案 0 :(得分:2)

使用带有常量种子的随机数。您可以使用Random(long seed)构造函数。

RandomStringUtils.random()方法可以接受Random来源,您可以使用所描述的常量种子创建该来源。

使用恒定种子对于使实验可重现非常有用 - 使用它们是一种非常好的做法,IMO。

答案 1 :(得分:1)

不要这样做。它让你头疼,使你的测试不可读,并没有给你带来任何好处。你已经看到了问题:约束的规范。所以,让我们去想象一下。你担心手动提供比随机数据更多的约束数据。但是你想每次都使用相同的数据(相同的种子)。那么你怎么知道随机数据比你手动提供的数据更好?你怎么知道你选择了种子呢?如果您不确定您的测试数据是否足够好,那么:

  • 简化你的代码(提取方法/类,避免ifs,避免空值,更多不可变和功能)
  • 查看边缘情况并将其包含在测试中
  • 查看生成的数据并检查其中一些数据是否与您的想法不同,并将这些数据添加到您的测试中
  • 使用突变测试
  • 每当发现开发,生产或生产的错误时,将这些数据添加到您的测试中
  • 做真正随机(不重复),长时间运行的测试。应记录每个破坏测试的生成数据,并将其添加到确定性单元测试中。

假装使用随机数据,你只是骗自己。数据不是随机的,您无法控制它,它会让您不再考虑代码的边缘情况。所以不要这样做,面对事实,让你的测试可读并检查更多条件

答案 2 :(得分:1)

您所描述的是基于属性的测试 - 最着名的例子是Haskell的快速​​检查。

http://www.haskell.org/haskellwiki/Introduction_to_QuickCheck1

有许多java端口,例如

Quickcheck哲学强调使用随机数据,但大多数(全部?)java端口允许您设置固定种子,以便生成的值可重复。

我从来没有真正尝试过这种方法,但是我希望通过将值与测试分开来使你的测试更具可读性(而不是像piotrek建议的那样可读性)。

如果了解值对于理解测试/ SUT行为很重要,那么这是错误的方法。