Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
716 views
in Technique[技术] by (71.8m points)

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

In F#, I have a record with a few fields:

    type myRecord = { a:float; b:float; c:float }

I am using FsCheck to test some properties which use this record. For (a contrived) example,

    let verify_this_property (r:myRecord) = myFunction(r) = (r.a * r.b) / r.c

Due to the internal implementation restrictions of myFunction, I would like to have FsCheck create test cases in which each of the fields a,b,c are restricted to non-negative floats.

I suspect this requires creating a generator for myRecord, but I have not been able to find any examples of how to do this.

Can anyone supply guidance?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 ;)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...