我有一个函数choose(elems) -> elem,它调用rand(),这使得它不确定。
为了能更好地测试这个,我想我可以把这个函数分成两部分,
generate_choices(elems, ...) -> distribution
choose(distribution) -> elem其中,choose()是rand()的一个薄包装器,generate_choices()生成一个可以从中绘制元素的发行版。然后,我可以确定地检验这种概率分布是否与预期的一样。
分布是一致的,但有两个条件:
elems,则均匀添加一个随机回退元素。elems,则一致添加一个随机默认元素。下面是一些例子:
generate_choices([a, b, c, d], [], []) -> [a, b, c, d]
generate_choices([a, b, c], [fallback1], []) -> [a, b, c, fallback1]
generate_choices([a, b, c], [fb1, fb2], []) -> [a, b, c, (fb1 | fb2)]
generate_choices([a, b], [fb1, fb2], [default1]) -> [a, b, (fb1 | fb2), default1]
generate_choices([a, b], [fb1, fb2], [d1, d2]) -> [a, b, (fb1 | fb2), (d1 | d2) ]
generate_choices([a], [fb1, fb2], [d1, d2]) -> [a, (fb1|fb2), (d1|d2) ]我的问题是:我应该如何建模distribution?
generate_choices()内部调用generate_choices()来填充回退和默认,那么我只能测试generate_choices()的一些确定性部分。(elems, fallback, default),那么generate_choices()是完全确定性的,但是choice()变得不那么琐碎了,无论如何都必须进行更彻底的测试。发布于 2018-04-25 15:47:19
使用随机数测试函数至少有两种方法。你可能想要这两种测试。
(1)一种方法是设置随机数发生器的初始状态并生成一些实例,并通过检验验证实例的正确性。然后将这些示例作为预期的输出放入您的测试脚本中,并在脚本开始时设置相同的初始状态。
(2)另一种检验是生成大量的实例,并验证了这些例子平均满足预期的性质。这是一个不确定的测试,因为对于随机数生成器生成的某些序列,测试可能会失败。您将不得不接受一些小的失败概率;好消息是,通过测试大量的示例并使测试的容忍度足够大,可以使概率变得足够小。
(2a)例如,在最简单的情况下,输入是序列,输出是序列的排列。如果你产生了大量的例子,你会发现所有的排列都有相同的频率,在一定的容忍范围内。显然,这个测试受测试输入长度的限制,因为有n个!长度为n的输入的排列。
您可以通过考虑每个不同排列的比例的分布来获得公差。每个置换的概率为1/n!,且每个置换的期望数目为(m乘以1/n!)其中m是生成的排列数。每个排列数的方差为(m乘以1/n!)次数(1 -1/n!)标准差是它的平方根。您可以将公差间隔近似为(预期数加或减去标准差的倍数)。通过更仔细地考虑分布,你可以得到一个更精确的间隔。
(2b)另一种检验排列的方法是观察输出的第一个元素等于输入的第一个元素的多少倍,输出的第一个元素等于第二个输入元素,第一个输入元素等于第三个输入元素,.,第二个输入元素,.,第三元素,输入的最后一个元素。这对于比测试2a更长的序列来说是可行的。同样,游戏的目的是找出每个垃圾箱中预期数的分布,并从中得到一个容差。
https://stackoverflow.com/questions/50003201
复制相似问题