首页 > 解决方案 > golang中单元测试的种子随机数

问题描述

我有用于math/rand从泊松和二项分布中“随机”采样的函数。它通常被其他也返回随机值的函数使用,例如h(g(f()))wheref() g()h()are random 函数。

每次程序运行时,我都会rand.Seed(n)拨打电话选择不同的种子,并且效果很好。main()

我的问题是针对这些 PRNG 函数的单元测试以及使用内置testing包使用它们的函数。我想消除随机性,以便我可以有一个可预测的值进行比较。

放置我的常数值种子以获得确定性输出的最佳位置在哪里?在测试文件的 init() 或每个测试函数内部,还是其他地方?

标签: testinggorandom

解决方案


你当然不应该把它放在测试init()函数中。为什么?因为执行顺序(或者即使运行测试函数)是不确定的。有关详细信息,请参阅如何按顺序运行 golang 测试?

这是什么意思?

如果您有 2 个测试函数(例如TestA()TestB()),这两个测试函数都调用math/rand,则您无法保证是否TestA()首先运行 或TestB(),或者即使其中任何一个将被调用。因此返回的随机数据math/rand将取决于此顺序。

更好的选择是将播种放入TestA()and TestB(),但这也可能不够,因为测试可能并行运行,因此返回的随机数据math/rand也可能是不确定的。

要真正获得确定性的测试结果,需要随机数据的函数需要接收一个math.Rand值并显式使用它,并且在测试中您可以创建math.Rand不会被其他测试使用的单独的、不同的值,因此将这些值播种为常量值并使用那些在测试函数中的,只有这样你才能得到确定的结果,而不依赖于测试函数的调用方式和顺序。


推荐阅读