我们希望在持续集成中将FsCheck用作我们的单元测试的一部分。因此,这种确定性和可复制的行为对我们非常重要。
作为一个随机测试框架,FsCheck可以生成有时可能会中断的测试用例。关键是,我们不仅要使用必须为每个输入保留的属性,例如List.rev >> List.rev === id
。但是,相反,我们进行一些数值处理,并且某些测试用例可能会因条件不佳而导致测试失败。
问题是:我们如何保证,一旦测试成功,它将永远成功?
到目前为止,我看到以下选项:
在这种情况下使用FsCheck的惯用方式是什么?
最佳答案
(我开始写评论,但是时间太长了,我认为它应该得到自己的回答)。
用FsCheck测试并非对每个输入都适用的属性是很常见的。例如,如果您为List.rev
运行,则FsCheck将琐碎地驳斥list<float>
示例。
数值稳定性本身就是一个棘手的问题-FsCheck中没有任何非确定性可归咎于此(FsCheck完全是确定性的,它只是一个输入生成器...)。您所指的“非确定性”可能是某些处理器中浮点运算中的错误等。但是即使在这种情况下,您是否也不想了解它们?而且,如果您的算法对于一类输入在数值上是不稳定的,那么您是否不想知道它呢?如果您不这样做,在我看来,您正在为生产中的某些真正的不确定性做好准备。
在FsCheck中,编写不适用于给定类型的所有输入的属性的惯用方式是编写生成器和收缩器。您可以使用==>
作为升级的步骤,但是它不能很好地扩展到复杂的前提条件。您说这可能会非常困难-从某种意义上说,这是对的,我保证您会学到有关您的代码的知识。好东西!
修复种子是一个坏主意,除了重现以前发现的错误外。我的意思是,在实践中,您将做什么:继续重新运行测试,直到通过为止,然后修复种子并声明“作业已完成”?