如果随机生成的输入没有用,我如何重新尝试基于 属性 的测试?
How can I re-try a property-based-test if the randomly-generated inputs are not useful?
我对单元测试一窍不通。我已经从 Nuget 安装了 FsCheck.Nunit
和 NUnitTestAdapter
,并且我正在尝试进行基于 属性 的测试,主要受到 the inestimable Scott Wlaschin.
的启发
我正在使用 [<Property>]
属性,我希望能够 "skip" 不符合测试要求的输入:
[<Property(MaxTest=10)>]
let ``Calling unzipTo with an invalid destination will yield a failure.`` badDest =
if Directory.Exists(badDest)
then // somehow skip to the next randomized input
else // do the actual test
最简单的方法是什么?
我更喜欢 FsCheck/NUnit 的答案(如果存在的话),但我也会考虑任何其他框架,其测试可以是 运行 in Visual Studio。 (我以为我看到了一些框架,其中有一个简单的函数可以做到这一点,但我不知道它是什么。)
到目前为止,我更喜欢 FsCheck.NUnit,因为它可以为 F# 类型(区分联合等)生成随机输入,而无需额外的工作。
我不是很熟悉 F# 或 fscheck,但如果您觉得这些状态更合适,NUnit 会提供 Assert.Ignore()
function, which will immediately stop the test and marked it as "ignored." You could also use Assert.Inconclusive()
or Assert.Pass()
。
你应该可以这样做:
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
模块定义的自定义运算符。如果 right-hand 端的条件计算为 true
.
,它只会强制计算惰性表达式
但是,请考虑重构此测试,使其不依赖于文件系统。文件系统是持久化的,所以会自动创建一个Persistent Fixture,也就是a lot of trouble to manage;并非无法应对,但最好避免。
此示例使用 FsCheck.Xunit,但 IIRC FsCheck.Nunit 的工作方式相同。不过,您应该认真考虑使用 FsCheck.Xunit 而不是 FsCheck.Nunit。 NUnit 2 的可扩展性模型非常差,这意味着大多数尝试扩展 NUnit 的 Glue 库都存在很多问题。这不是 FsCheck.Nunit 的问题,而是 NUnit 本身的问题,但它会给您带来很多麻烦。
FsCheck.Prop.discard()
似乎在做我想做的事情——当我 运行 进行日志记录测试时,我可以看到一些尝试被丢弃了,但是 10 运行 没有完成被丢弃。
==>
运算符用于 运行 与 FsCheck.Quick
或类似的测试。但是,这需要惰性部分采用“可测试”的格式,我目前正在编写的测试只是 <inputs>->unit
.
我对单元测试一窍不通。我已经从 Nuget 安装了 FsCheck.Nunit
和 NUnitTestAdapter
,并且我正在尝试进行基于 属性 的测试,主要受到 the inestimable Scott Wlaschin.
我正在使用 [<Property>]
属性,我希望能够 "skip" 不符合测试要求的输入:
[<Property(MaxTest=10)>]
let ``Calling unzipTo with an invalid destination will yield a failure.`` badDest =
if Directory.Exists(badDest)
then // somehow skip to the next randomized input
else // do the actual test
最简单的方法是什么?
我更喜欢 FsCheck/NUnit 的答案(如果存在的话),但我也会考虑任何其他框架,其测试可以是 运行 in Visual Studio。 (我以为我看到了一些框架,其中有一个简单的函数可以做到这一点,但我不知道它是什么。)
到目前为止,我更喜欢 FsCheck.NUnit,因为它可以为 F# 类型(区分联合等)生成随机输入,而无需额外的工作。
我不是很熟悉 F# 或 fscheck,但如果您觉得这些状态更合适,NUnit 会提供 Assert.Ignore()
function, which will immediately stop the test and marked it as "ignored." You could also use Assert.Inconclusive()
or Assert.Pass()
。
你应该可以这样做:
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
模块定义的自定义运算符。如果 right-hand 端的条件计算为 true
.
但是,请考虑重构此测试,使其不依赖于文件系统。文件系统是持久化的,所以会自动创建一个Persistent Fixture,也就是a lot of trouble to manage;并非无法应对,但最好避免。
此示例使用 FsCheck.Xunit,但 IIRC FsCheck.Nunit 的工作方式相同。不过,您应该认真考虑使用 FsCheck.Xunit 而不是 FsCheck.Nunit。 NUnit 2 的可扩展性模型非常差,这意味着大多数尝试扩展 NUnit 的 Glue 库都存在很多问题。这不是 FsCheck.Nunit 的问题,而是 NUnit 本身的问题,但它会给您带来很多麻烦。
FsCheck.Prop.discard()
似乎在做我想做的事情——当我 运行 进行日志记录测试时,我可以看到一些尝试被丢弃了,但是 10 运行 没有完成被丢弃。
==>
运算符用于 运行 与 FsCheck.Quick
或类似的测试。但是,这需要惰性部分采用“可测试”的格式,我目前正在编写的测试只是 <inputs>->unit
.