我必须从我的数据库中返回一个随机条目。
我编写了一个函数,因为我在Python中使用random
模块,所以除非我以愚蠢的方式使用它。否则它可能会使用它。
现在,我如何编写一个检查此功能是否有效的单元测试?毕竟,如果它是一个很好的随机值,你永远不会知道。
我不是偏执狂,我的功能并不复杂,Python标准库是1000 x 时间足够我的目的。我不是在做密码学或者是一些关键的东西。我只是想知道是否有办法。
答案 0 :(得分:19)
RANDOM.ORG for testing randomness列出了几项统计测试。请参阅链接文章的最后两部分。
另外,如果您可以获得Beautiful Testing的副本,那么John D. Cook的整个章节称为测试随机数生成器。他解释了上面文章中列出的许多统计方法。如果您真的想了解RNG,那么这一章是一个非常好的起点。我自己写过这个主题,但约翰在解释它方面做得更好。
答案 1 :(得分:6)
答案 2 :(得分:2)
您可以让单元测试多次调用该函数,并确保碰撞次数相当低。例如。如果您的随机结果在1-1000000范围内,请调用该函数100次并记录结果;然后检查是否有重复。如果存在任何(或多于1次碰撞,取决于您对假测试失败的恐惧程度),则测试失败。 显然不完美,但如果随机数来自Dilbert,它会抓住它: http://www.random.org/analysis/
答案 3 :(得分:2)
你有两个纠结的问题。第一个问题是测试您的随机选择是否有效。播种PRNG允许您编写一个确定性且可以断言的测试。这应该让你对你的代码有信心,因为底层函数不负责任(即随机返回一个足够好的随机值流)。
你似乎关心的第二个问题是python的随机函数。您希望将有关随机函数的代码问题与音乐会分开。有一些randomness tests你可以read about但是在一天结束时除非你正在进行加密,否则我相信python开发人员已经足够正确了。
答案 4 :(得分:1)
答案 5 :(得分:0)
就像上面的答案一样,我可以重复一遍,它确实很大程度上取决于您要测试的内容。
我们在代码中有很多地方需要确保程序员错误不会导致非随机字节作为AES或EC私钥等传入。
我担心的错误的具体性质更多地是关于1.字节序列模式和2.整体bigint值不是随机分布的。您可以在单元测试中看到我们担心的事情清单。
不想处理到处安装numpy并进行大量非常昂贵的测试,我编写了一组廉价的基本测试来解决我们在代码中寻找的特定问题:
无论如何,您可以做同样的事情。使用下面的临时代码的修改版本,并生成关于您认为是很好的随机性来源的统计信息。然后与您可疑的来源进行比较。
https://github.com/earonesty/dotfiles/blob/master/randbytestest.py
摘要:
randbytestest.py -b -l 1024 -i 10000
randbytestest.py -b -l 32 -i 10000
randbytestest.py -b -l 16 -i 10000
绝对不严格。但是它也可以检测并防止我们所关注的所有问题。