【问题标题】:Unit testing a method with random behaviour对具有随机行为的方法进行单元测试
【发布时间】:2010-09-28 19:28:50
【问题描述】:

我正在为我正在开发的游戏编写单元测试用例。游戏开始时,玩家的位置是随机的,我有两个问题:

  1. 由于播放器的位置是随机的,我无法确定通过一次的测试用例是否会再次通过。例如,它可以在大部分时间通过,但如果玩家碰巧位于障碍物前面,它就会失败。
  2. 我必须在一个测试用例中测试所有情况。例如,在测试玩家移动是否正确时,我必须检查是否有障碍物以及是否被算法考虑。

我对此并不满意,但我看不到出路。测试具有部分随机行为的方法是否可以接受?

【问题讨论】:

标签: unit-testing


【解决方案1】:

我建议您将随机源(随机数生成器或其他)视为依赖项。然后,您可以通过提供假 RNG 或具有已知种子的 RNG 来使用已知输入对其进行测试。这消除了测试中的随机性,同时将其保留在真实代码中。

如果你伪造了 RNG,你可以测试如果它自然地将玩家定位在障碍物上会发生什么 - 它如何将玩家移开等等。当然,这取决于知道类如何使用 RNG,但就我个人而言,我很高兴单元测试充当具有一些内部知识的“白盒测试”。

【讨论】:

  • 也就是说你建议我为我的游戏提供一个随机数生成器,我可以用它创建一个模拟实现?
  • 嗯。但是随机数生成器会用于几件事,所以真的很难伪造它。例如,它也用于玩家颜色(对游戏的任何其他方面没有影响的东西,所以我忽略它)。我看到的唯一方法是创建一个包含“getRandomPlayerPosition()”和“getRandomPlayerColor()”等方法的生成器类,然后我可以伪造它。这样可以吗?
  • @forceal:是的,这很好,也更容易控制。那么你的“真正的”生成器类可能非常简单,不需要太多测试。
  • @forceal - “诀窍”是要意识到此时您不是在测试随机性,而是在测试代码对 0 到 1 之间的数字的响应。
  • 效果很好!我创建了一个接口“RNG”,它具有“getRandomPlayerPosition()”和“getRandomPlayerColor()”等方法。我的游戏现在是使用 RNG 实例创建的。对于测试,它使用“MockRNG”实现,它具有位置和颜色的设置方法。在生产中,它使用“JavaRNG”,它使用 Java 的随机数机制来返回值。
【解决方案2】:

您可以采取的一种方法是将随机位置生成拆分为单独的类/接口,以便您可以在测试中覆盖它,从而控制它。

【讨论】:

    【解决方案3】:

    将随机源作为测试的输入,并将其配置为每次都相同。

    几乎所有随机数生成器都采用“种子”值。通过每次提供相同的种子值,您可以知道您将获得相同的随机数序列,因此您的应用程序的输出应该完全相同。

    我必须在一个测试用例中测试所有情况。

    为什么?您可以有多个测试用例。您可以选择任意数量的不同和任意随机数种子来创建要测试的条件。或者干脆将随机定位替换为特定定位以进行测试。

    【讨论】:

      【解决方案4】:

      这里有两个不同的东西要测试,你应该分别测试它们:

      • 程序逻辑是否适用于所有可能的起始位置?通过将播放器非随机定位在多个位置来测试这一点,尝试涵盖所有“特殊情况”。
      • 随机定位真的是随机的吗?通过多次调用定位逻辑进行测试,并进行某种统计分析。

      【讨论】:

        【解决方案5】:

        正如其他答案所说,随机算法是确定性的。如果你使用相同的种子,你可以重现一个序列。

        我必须处理非确定性代码的唯一情况是涉及多线程时。那么,你就依赖于操作系统的调度器了。

        在这些情况下,我将单元测试编写为一个循环,它会重复数千次测试代码。

        【讨论】:

          【解决方案6】:

          根据测试理论,不可能测试随机行为 :) 另一方面,正如之前的答案所说,对于您的测试,您可以以某种方式进行伪随机活动。

          【讨论】:

            猜你喜欢
            • 2010-09-10
            • 1970-01-01
            • 2019-08-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-14
            • 2012-07-18
            相关资源
            最近更新 更多