如果随机生成的输入无用,我该如何重新尝试基于属性的测试?

时间:2016-01-07 13:45:13

标签: .net f# nunit fscheck property-based-testing

我是单元测试的n00b。我已经从Nuget安装了p value = options.map { |o| value = o[:desired] }.compact.first FsCheck.Nunit,我正在尝试进行基于属性的测试,主要受到the inestimable Scott Wlaschin的启发。

我正在使用NUnitTestAdapter属性,我希望能够“跳过”不符合测试要求的输入:

[<Property>]

最简单的方法是什么?

我更喜欢FsCheck / NUnit的答案,如果它存在,但我也会考虑其他测试可以在Visual Studio中运行的框架。 (我以为我看到了一个框架,其中有一个简单的函数来完成这个,但我无法弄清楚它是什么。)

到目前为止,我更喜欢FsCheck.NUnit,因为它可以为F#类型(有区别的联合等)生成随机输入而无需额外的工作。

3 个答案:

答案 0 :(得分:6)

你应该可以这样做:

open FsCheck
open FsCheck.Xunit

[<Property(MaxTest=10)>]
let ``Calling unzipTo with an invalid destination will yield a failure.`` badDest =
    (not Directory.Exists(badDest)) ==> lazy
    // do the actual test

第一行是布尔条件,==>FsCheck模块定义的自定义运算符。如果右侧的条件评估为true,它只会强制评估惰性表达式。

但是,请考虑重构此测试,以使其不依赖于文件系统。文件系统是持久的,因此自动创建持久性夹具​​,a lot of trouble to manage;并非不可能处理,但最好避免。

此示例使用 FsCheck.Xunit ,但IIRC FsCheck.Nunit 的工作方式相同。但是,您应该认真考虑使用 FsCheck.Xunit 而不是 FsCheck.Nunit 。 NUnit 2的可扩展性模型非常差,这意味着大多数试图扩展NUnit的Glue Libraries都会遇到很多问题。这不是 FsCheck.Nunit 的问题,但是使用NUnit本身,但它会为你带来很多麻烦。

答案 1 :(得分:1)

FsCheck.Prop.discard()似乎做了我想做的事情 - 当我使用日志记录运行测试时,我可以看到一些尝试被丢弃,但是10次运行完成而没有被丢弃。

==>运算符用于运行FsCheck.Quick或类似的测试。但是,这要求延迟部分采用“可测试”的格式,我目前正在编写的测试只是<inputs>->unit

答案 2 :(得分:0)

我对F#或fscheck并不十分熟悉,但NUnit提供Assert.Ignore()功能,它会立即停止测试,并将其标记为&#34;忽略。&#34;如果你觉得那些是更合适的状态,你也可以使用Assert.Inconclusive()Assert.Pass()