如何为随机输出编写jUnit测试?

时间:2014-06-25 23:25:28

标签: java random junit

与编写具有一部分随机性的代码的测试相比,测试具有预定义输入和输出参数的代码相对容易,因为我们必须检查随机生成器是否有偏差。

使用随机数的库的一个示例是java.util.Collections.shuffle(List<?> list),它在http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle之后对一组对象进行混洗。

如何为具有随机输出的代码编写jUnit测试?不仅适用于洗牌,还可以测试随机性。

1 个答案:

答案 0 :(得分:2)

除非您正在编写实际的随机数生成器或某种依赖于安全随机数生成器的加密库,否则您不需要检查随机数生成器是否有偏差。这是随机数生成器的作者的工作。

你的Collections.shuffle()示例也是一个很糟糕的例子,因为它是一个内置的JDK方法。没有理由测试内置的JDK方法,Java的作者已经为您以及过去20年中使用过这些方法的数百万用户做过这样的事情。您是否也有测试确认System.out.print()也按预期工作?

单元测试应该是确定性的。一遍又一遍地重复相同的测试应该每次产生相同的结果。如果它们没有,并且测试失败,它是否会失败,因为代码有问题,或者因为非确定性输出产生无效输入?如果在重新运行结果时,测试通过,是因为错误是修复的还是因为我们碰巧得到随机输入?

由于这些原因,您的单元测试应该尝试模拟或删除任何随机性。也许编写几个测试来执行数据的特定转换以测试边界条件。例如,对于shuffle(),可能有一个测试按特定顺序重新排序元素,或者按升序或降序对元素进行排序,或者测试没有实际进行任何变换等。这些都是有效的结果这可能是随机发生的。

这样,每次测试都会为同一输入生成相同的输出,并且您可以获得不同结果的好处。

修改 看来你真的想测试自己的随机数生成器。

以下链接描述了您应该做的统计测试,以确定它是否真的是随机的(或至少是随机的)

RANDOM.ORG statistical analysis

NIST statistical test suite