In FsCheck, how to generate a test record with non-negative fields?

守給你的承諾、 提交于 2019-11-29 14:12:14

Try this:

type Generators = 
    static member arbMyRecord =
        fun (a,b,c) -> { myRecord.a = a; b = b; c = c }
        <!> (Arb.generate<float> |> Gen.suchThat ((<) 0.) |> Gen.three)
        |> Arb.fromGen

Arb.register<Generators>() |> ignore
Check.Quick verify_this_property

The <!> is an infix map, useful for applicative style. This is an equivalent generator:

type Generators = 
    static member arbMyRecord =
        Arb.generate<float> 
        |> Gen.suchThat ((<) 0.) 
        |> Gen.three
        |> Gen.map (fun (a,b,c) -> { myRecord.a = a; b = b; c = c })
        |> Arb.fromGen

If you don't want to globally register your generator, you can use forAll:

Check.Quick (forAll Generators.arbMyRecord verify_this_property)

Shrinking left as an exercise ;)

You can avoid creating custom generator by using FsCheck conditional properties

let verify_this_property (r:myRecord) =
    (r.a > 0.0 && r.b > 0.0 && r.c > 0.0) ==> lazy (myFunction r = (r.a * r.b) * r.c)

Though this will result in (substantially?) slower execution of the test since FsCheck will have to discard all unsuitable test entries.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!