Ruby:在代码中使用rand(),但编写测试来验证概率

我有一些代码可以根据加权随机提供的东西.重量更重的东西更有可能随机选择.现在我是一个很好的 rubyist,我想用测试来覆盖所有这些代码.我想测试根据正确的概率获取的东西.

那么我该如何测试呢?为随机的东西创建测试会使实际与预期的比较变得非常困难.我有一些想法,以及为什么它们不会很好用:

> Stub Kernel.rand在我的测试中返回固定值.这很酷,但rand()被多次调用,我不确定我是否可以通过足够的控制来测试它以测试我需要的东西.
>获取一个随机项很多次,并比较实际比率与预期比率.但除非我可以无数次运行它,否则这将永远不会是完美的,如果我在RNG中运气不好,可能会间歇性地失败.
>使用一致的随机种子.这使RNG可重复,但它仍然没有给我任何验证项目A将在80%的时间发生(例如).

那么我可以使用什么样的方法来编写随机概率的测试覆盖率?

解决方法

我认为你应该分开你的目标.一个是你提到的存根Kernel.rand.以rspec为例,你可以这样做:
test_values = [1,2,3]
Kernel.stub!(:rand).and_return( *test_values )

请注意,除非您使用Kernel作为接收器调用rand,否则此存根将不起作用.如果你只是调用“rand”,那么当前的“self”将收到消息,你实际上会得到一个随机数而不是test_values.

第二个目标是执行类似于实际生成随机数的字段测试.然后,您可以使用某种公差来确保接近所需的百分比.这永远不会是完美的,并且可能需要人来评估结果.但它仍然有用,因为您可能会意识到另一个随机生成器可能更好,例如从/ dev / random读取.此外,进行这种测试是很好的,因为假设你决定迁移到一种新的平台,它的系统库不能很好地产生随机性,或者在某个版本中存在一些错误.测试可能是一个警告标志.

这真的取决于你的目标.你只想测试你的加权算法,还是随机性?

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...