How can I get repeatable async tests with FsCheck? Here is a sample code that I run in FSI:
let prop_simple() = gen {
let! s = Arb.generate<string>
printfn "simple: s = %A" s
return 0 < 1
}
let prop_async() =
async {
let s = Arb.generate<string> |> Gen.sample 10 1 |> List.head
// let! x = save_to_db s // for example
printfn "async: s = %A" s
return 0 < 1
}
|> Async.RunSynchronously
let check_props() =
//FC2.FsCheckModifiers.Register()
let config =
{ FsCheck.Config.Default with
MaxTest = 5
Replay = Random.StdGen(952012316,296546221) |> Some
}
Check.One(config, prop_simple)
Check.One(config, prop_async)
The output looks something like this:
simple: s = "VDm2JQs5z"
simple: s = "NVgDf2mQs8zaWELndK"
simple: s = "TWz3Yjl2tHFERyrMTvl0HOqgx"
simple: s = "KRWC92vBdZAHj6qcf"
simple: s = "CTJbQGXzpLBNn0RY6MCvlfUtbQhCUKm9tbXFhLSu0RcYmi"
Ok, passed 5 tests.
async: s = "aOE"
async: s = "y8"
async: s = "y8"
async: s = "q"
async: s = "q"
Ok, passed 5 tests.
Another run can look like this:
simple: s = "VDm2JQs5z"
simple: s = "NVgDf2mQs8zaWELndK"
simple: s = "TWz3Yjl2tHFERyrMTvl0HOqgx"
simple: s = "KRWC92vBdZAHj6qcf"
simple: s = "CTJbQGXzpLBNn0RY6MCvlfUtbQhCUKm9tbXFhLSu0RcYmi"
Ok, passed 5 tests.
async: s = "g"
async: s = "g"
async: s = "g"
async: s = ""
async: s = ""
Ok, passed 5 tests.
So prop_simple()
works fine & is repeatable (given StdGen(952012316,296546221)
).
But prop_async()
is not repeatable & seems to generate the same strings over and over.
Also, is there a better way to write prop_async()
?