我对使用随机性的单元测试功能的最佳实践技术(如果有的话)感兴趣.要明确的是,我是,而不是,负责测试随机数生成器的分布。
作为一个玩具示例,让我们考虑一下这个函数:
// Returns a random element from @array. @array may not be empty.
int GetRandomElement(int[] array);this question的答案表明,我们可以注入一个模拟的随机性源,这是有意义的。但我不确定我该怎么用模拟。例如,让我们假设我们有这个接口:
// A mock-friendly source of randomness.
interface RandomnessSource {
// Returns a random int between @min (inclusive) and @max (exclusive).
int RandomInt(int min, int max);
}...And将GetRandomElement()的签名更改为:
// Returns a random element from @array, chosen with @randomness_source.
// @array may not be empty.
int GetRandomElement(int[] array, RandomnessSource randomness_source);好吧,现在一个测试看起来是:
MockRandomnessSource mock = new MockRandomnessSource();
mock.ExpectCall(RandomnessSource::RandomInt(0, 5)).Return(2);
AssertEquals(GetRandomElement({0, 10, 20, 30, 40}, mock), 20);...which可以正常工作,但只有在实现如下所示的情况下才能工作:
// A fairly intuitive implementation.
int GetRandomElement(int[] array, RandomnessSource randomness_source) {
// Pick a random number between [0..n), where @n is the @array's legnth.
return array.Get(randomness_source.RandomInt(0, array.Length()));
}...But函数规范中的任何内容都不能阻止这样的实现:
// Less intuitive, but still a conforming implementation.
int GetRandomElement(int[] array, RandomnessSource randomness_source) {
// Pick a random number between [1..n+1), only to subtract 1 from it.
return array.Get(randomness_source.RandomInt(1, array.Length() + 1) - 1);
}一个突然想到的想法是,我们可能会进一步限制函数的契约,如下所示:
// Returns a random element from @array, chosen with @randomness_source by
// by calling @RandomnessSource::RandomInt to pick a random index between
// 0 and the length of @array.
int GetRandomElement(int[] array, RandomnessSource randomness_source);...But --我无法完全克服这样的印象,即这给函数契约带来了太大的限制。
我还怀疑,可能有更好的方法来定义接口RandomnessSource,使其调用者更容易接受单元测试,但我不太确定是什么/如何。
...Which给我带来了一个问题:使用随机性的单元测试功能的最佳实践技术(如果有的话)是什么?
发布于 2017-12-25 06:29:48
通常你不想对“随机性”进行单元测试。单元测试主要用于确定预期的输入是否会给出预期的输出。非常有定义和结构。您希望单元测试是非常可预测的,并且每次运行测试时都以相同的方式运行。
如果你真的想测试它,那么问题就变成了你到底想要如何测试它?如果两个测试之间的结果是不同的,会发生什么情况?如何定义成功的测试和失败的测试?
在通常的单元测试中,这些问题都更加明显,因为这些测试的结果非常清楚,而且事先定义得很清楚。
https://stackoverflow.com/questions/47966071
复制相似问题