固有随机/非确定性算法的单元测试
简而言之,我当前的项目涉及“约束随机事件”的创建。我基本上是在制定检查时间表。其中一些是基于严格的计划约束;您每周星期五10:00 AM进行一次检查。其他检查是“随机的”;有一些基本的可配置要求,例如“每周必须进行3次检查”,“必须在9 AM-9PM的时间之间进行检查”以及“在同一8小时内不应进行两次检查”,但是在为一组特定的检查配置的任何限制内,得出的日期和时间均不可预测。 单元测试和TDD,IMO在此系统中具有巨大的价值,因为它们可以用于按增量方式构建它,而整套需求仍然不完整,并确保我不会“过度设计”它来做我不喜欢的事情目前不知道我需要。严格的时间表对TDD来说是小菜一碟。但是,当我为系统的随机部分编写测试时,我发现很难真正定义要测试的内容。我可以断言调度程序产生的所有时间都必须在约束范围内,但是我可以实现通过所有此类测试的算法,而实际时间却不是很“随机”。实际上,这正是发生的事情。我发现了一个问题,尽管时间无法精确预测,但它属于允许的日期/时间范围的一小部分。该算法仍然通过了我认为我可以合理做出的所有断言,并且我无法设计在这种情况下会失败的自动测试,但是在给出“更多随机”结果时通过。我必须证明该问题是通过重组一些现有测试以重复多次来解决的,并目视检查生成的时间是否在整个允许范围内。 有没有人提供设计非预期行为的提示? 感谢所有的建议。主要观点似乎是,我需要进行确定性测试才能获得确定性,可重复性和可肯定的结果。说得通。 我创建了一组“沙盒”测试,其中包含用于约束过程(可能为任意长的字节数组在最小值和最大值之间变长的过程)的候选算法。然后,我通过一个FOR循环运行该代码,该循环为该算法提供了几个已知的字节数组(刚开始时从1到10,000,000的值),并使该算法将每个值限制为1009到7919之间的值(我使用质数来确保算法不会在输入和输出范围之间经过一些偶然的GCF)。计算得到的约束值,并生成直方图。要“通过”,所有输入都必须反映在直方图中(为了确保我们不会“丢失”任何值),直方图中任意两个存储桶之间的差不能大于2(实际上应小于等于1) ,但请继续关注)。获胜的算法(如果有)可以直接剪切并粘贴到生产代码中,并进行永久测试以进行回归。 这是代码: private void TestConstraintAlgorithm(int min, int max, Func<byte[], long, long, long> constraintAlgorithm) { var histogram = new int[max-min+1]; for (int i = 1; i <= 10000000; i++) { //This is the stand-in for the PRNG; produces a known byte array var buffer …