我有一个深层嵌套的数据结构,到处都有浮点数。 在序列化然后反序列化之后,我使用FsCheck检查数据是否未更改。
当浮动是NaN或+/-无穷大时,此属性失败,但是,这种情况并不令我感兴趣,因为我不希望这些值出现在实际数据中。 / p>
有没有办法防止FsCheck产生NaN和无穷大?
我已经尝试丢弃包含所述值的生成数据,但是这使得测试非常慢,实际上很慢,测试仍在运行,而我写这篇文章时,我怀疑它实际上是光洁度...
答案 0 :(得分:8)
对于包含浮点数的反射生成类型(我怀疑您正在使用),您可以通过编写类来覆盖浮点数的默认生成器,如下所示:
type Overrides() =
static member Float() =
Arb.Default.Float()
|> filter (fun f -> not <| System.Double.IsNaN(f) &&
not <| System.Double.IsInfinity(f))
然后致电:
Arb.register<Overrides>()
在FsCheck尝试生成类型之前;例如在您的测试设置中或在调用Check.Quick之前。
您可以检查register方法的结果,看看它如何将默认的任意实例与新的实例合并;它应该覆盖它们。
如果您使用的是xUnit扩展,则可以使用PropertyAttribute的Arbitraries参数来避免调用Arb.register:
[<Property(Arbitraries=Overides)>]
答案 1 :(得分:6)
正如Mauricio Scheffer所说,你可以在测试参数中使用NormalFloat类型。
浮点列表的简单示例:
open FsCheck
let f (x : float list) = x |> List.map id
let propFloat (x : float list) = x = (f x)
let propNormalFloat (xn : NormalFloat list) =
let x = xn |> List.map NormalFloat.get
x = f x
Check.Quick propFloat
//Falsifiable, after 18 tests (13 shrinks) (StdGen (761688149,295892075)):
//[nan]
Check.Quick propNormalFloat
//Ok, passed 100 tests.