我有一些代码可以根据加权随机数传送内容。重量更大的东西更有可能被随机选择。现在,作为一名优秀的 ruby 专家,我想用测试覆盖所有这些代码。我想测试事物是否已根据正确的概率获取。

那么我该如何测试呢?为应该是随机的东西创建测试将使比较实际值与预期值非常困难。我有一些想法,以及为什么它们行不通:

在我的测试中,将

  • Stub Kernel.rand返回固定值。这很酷,但是rand()被多次调用,我不确定我是否可以使用足够的控件来绑定(bind)它来测试我需要的东西。
  • 大量提取随机项目,然后比较实际比率与预期比率。但是,除非我可以无限次运行它,否则它将永远不会是完美的,并且如果我在RNG中遇到不幸的话,可能会间歇性地失败。
  • 使用一致的随机种子。这使得RNG可以重复,但是仍然没有提供任何证据证明项目A将在80%的时间发生(例如)。

  • 那么,我可以使用哪种方法为随机概率编写测试覆盖率?

    最佳答案

    我认为您应该分开目标。正如您提到的,其中之一是对Kernel.rand进行 stub 。例如,使用rspec,您可以执行以下操作:

    test_values = [1, 2, 3]
    Kernel.stub!(:rand).and_return( *test_values )
    

    请注意,除非您使用内核作为接收者来调用rand,否则该 stub 将不起作用。如果您仅调用“rand”,那么当前的“self”将收到该消息,并且您实际上将获得一个随机数而不是test_values。

    第二个目标是做一些像现场测试这样的事情,在其中您实际生成随机数。然后,您将使用某种容忍度来确保您接近所需的百分比。但是,这永远不会是完美的,并且可能需要人工来评估结果。但是这样做仍然很有用,因为您可能意识到另一个随机数生成器可能更好,例如从/dev/random中读取。同样,进行这种测试也是很好的,因为假设您决定迁移到一种新的平台,该平台的系统库不擅长生成随机性,或者某个版本中存在某些错误。该测试可能是一个警告信号。

    这确实取决于您的目标。您只想测试加权算法,还是随机性?

    10-05 20:33
    查看更多