Search code examples
f#xunitfscheckproperty-based-testing

FsCheck not using registered Arbs/Gens


I am trying to use FsCheck for Property based testing but I cannot seem to figure out how to get FsCheck to use the gens I have registered. Here is the code for generating types for the domain:

module Flips.Gens

open Flips.Domain
open FsCheck

type Silly = {
    Name : string
}

let SillyGen () =
    gen {
        let! NonEmptyString name = Arb.generate<NonEmptyString>
        return { Name = name}
    }

type Domain () =
    static member ArbSillyGen () = Arb.fromGen (SillyGen ())

Here is the example test

module Flips.Tests

open Xunit
open FsCheck
open FsCheck.Xunit
open Flips.Gens

do Arb.register<Domain> () |> ignore

module Tests =

    [<Property>]
    let ``Silly Name is NonEmptyString`` (silly:Silly) =
        let isNullOrEmpty = System.String.IsNullOrEmpty silly.Name
        Assert.True(not isNullOrEmpty)

I have two problems:

  1. It does not appear that FsCheck is using the generators I have provided because it is generating Silly types with a name that is empty.

  2. I try setting a breakpoint in the gen for the Silly type but it is never hit so I can't figure out what is going on.

I've done this before in other projects but for some reason I'm hitting a brick wall.


Solution

  • FsCheck + xunit handles arbitraries in a different way. Per the documentation here, I would try and run the test this way:

    module Tests =

    [<Property(Arbitrary = [| typeof<Domain> |] )>]
    let ``Silly Name is NonEmptyString`` (silly:Silly) =
        let isNullOrEmpty = System.String.IsNullOrEmpty silly.Name
        Assert.True(not isNullOrEmpty)
    

    You can delete do Arb.register<Domain> () |> ignore