【问题标题】:Writing a JUnit test for a random number generator为随机数生成器编写 JUnit 测试
【发布时间】:2013-02-11 11:08:12
【问题描述】:

我有一个方法可以返回 0 到 10 之间的随机数。

public int roll(){
    int pinsKnockedDown = (int) (Math.random() * 10);
    return pinsKnockedDown;
}

我将如何为此编写 JUnit 测试?到目前为止,我已经将调用置于一个循环中,因此它运行了 1000 次并且如果测试失败 - 数字小于 0 - 数量超过 10 个

我如何测试所有的数字不一样,即

【问题讨论】:

  • 运行多次(数百万次),计算每个数字的出现次数并确定它是否足够随机。例如:en.wikipedia.org/wiki/Statistical_randomness
  • 您可能想要接近均匀分布的东西。这不是您可以通过单元测试轻松“测试”的东西,而不是证明您的 RNG 为您想要的范围产生均匀分布可能会更容易(并且可以说更有用)..
  • 我不会。这是单元测试发疯了。代码的形式保证了结果。您不必测试库 API 或乘以十。

标签: java random junit


【解决方案1】:

您想测试您的代码,而不是 Java 提供的 Math.random() 的质量。假设 Java 方法是好的。所有测试都是正确性的必要条件,但不是充分条件。因此,请选择一些测试来发现使用 Java 提供的方法时可能出现的编程错误。

您可能会测试以下内容:最终,在连续调用之后,该函数将每个数字至少返回一次,而不会返回任何超出所需范围的数字。

【讨论】:

    【解决方案2】:

    Randomness tests 可能很复杂。例如在上面你只是想确保你得到 1 到 10 之间的数字吗?您想确保均匀分布等吗?在某个阶段,我建议您信任 Math.random() 并确保您没有搞砸限制/范围,这基本上就是您正在做的事情。

    【讨论】:

      【解决方案3】:

      我的答案已经有缺陷,我需要返回一个 0-10 的数字,但我原来的帖子只返回了 0-9 的范围!这是我发现的方法...

      循环 100k 次并确保范围正确,它应该是 0-10(虽然我已将 10 设置为变量,以便代码可以重复使用)。

      我还存储了循环期间找到的最高和最低值,它们应该位于刻度的最末端。

      如果最高值和最低值相同,则表明有人伪造了随机数返回。

      我看到的唯一问题是该测试可能出现假阴性,但不太可能。

      @Test
      public void checkPinsKnockedDownIsWithinRange() {
          int pins;
          int lowestPin = 10000;
          int highestPin = -10000;
      
          for (int i = 0; i < 100000; i++) {
              pins = tester.roll();
              if (pins > tester.NUMBER_OF_PINS) {
                  fail("More than 10 pins were knocked down");
              }
              if (pins < 0) {
                  fail("Incorrect value of pins");
              }
      
              if (highestPin < pins) {
                  highestPin = pins;
              }
      
              if (lowestPin > pins) {
                  lowestPin = pins;
              }
          }
      
          if (lowestPin == highestPin) {
              fail("The highest pin count is the same as the lowest pin count. Check the method is returning a random number, and re-run the test.");
          }
      
          if (lowestPin != 0) {
              fail("The lowest pin is " + lowestPin + " and it should be zero.");
          }
      
          if (highestPin != tester.NUMBER_OF_PINS) {
              fail("The highest pin is " + highestPin + " and it should be " + tester.NUMBER_OF_PINS + ".");
          }
      
      }
      

      【讨论】:

      • 除此之外 - 我最终完全更改了我的代码并使用测试数据来确保我的代码是正确的,而不是针对随机生成器进行测试。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-24
      • 1970-01-01
      • 2013-01-14
      • 2013-01-30
      • 1970-01-01
      相关资源
      最近更新 更多