如何使用fscheck仅生成数据?

3

是否有可能使用fscheck生成数据,特别是列表,以供fscheck之外的使用?我在fscheck测试中无法调试一种情况,似乎比较结果相等,但fscheck表示它们不相等。

我有一个用于对象列表的生成器。如何从这个生成器生成可供使用的列表?

let genListObj min max  = Gen.listOf Arb.generate<obj> |> Gen.suchThat (fun l -> (l.Length >= min) && (l.Length <= max))

使用 Gen.eval,请参见 http://fscheck.codeplex.com/SourceControl/changeset/view/fd9da99ee77d#FsCheck.Test%2fHelpers.fs。但是 FsCheck 会输出生成的数据以便于查找失败的原因,所以通常不需要这样做。 - Mauricio Scheffer
我想我尝试了Gen.eval。我会再看一下。对我来说不明显的是,fsCheck在属性测试中输出这些数据的位置。现在将一些有趣的东西提交到我的公共分支,并向问题#98发布一个长消息。 - Jack Fox
1
顺便提一下,避免使用Gen.suchThat。它基本上会生成随机值,直到有些值通过筛选器,因此可能需要很长时间。对于您的示例,最好先生成一个随机长度(使用例如Gen.choose),然后生成该长度的列表(使用Gen.listOfLength)。 - Kurt Schelfthout
感谢您提供关于Gen.listOfLength的提示。我不知道我怎么会忽略它。 - Jack Fox
Gen.eval需要Random.StdGen。我想从我构建的Gen中生成数据(通过Arb.fromGen在FsCheck中工作),并且可以访问实际数据以进行进一步处理。 - Jack Fox
1
FsCheck默认情况下不会设置这个,但编写一个函数相当容易。如果您发布实际属性,我认为我可以更好地帮助您 - 特别是我不理解“fscheck说它们不是” - fscheck对相等没有任何特殊想法。 - Kurt Schelfthout
1个回答

7

编辑:这个函数现在已经成为FsCheck API的一部分(Gen.sample),所以您不再需要以下内容...

这是一个生成给定生成器中n个样本的示例函数:

let sample n gn  = 
   let rec sample i seed samples =
       if i = 0 then samples
       else sample (i-1) (Random.stdSplit seed |> snd) (Gen.eval 1000 seed gn :: samples)
   sample n (Random.newSeed()) []

编辑:这里的1000是生成值的大小。1000相当大,例如序列将在0和1000个元素之间,字符串也是如此。如果生成需要很长时间,您可能需要调整该值(或将其作为函数的参数传入)。


哇!到目前为止完美无缺,甚至在返回我的自定义数据结构和列表的 gen 上也能正常工作。非常感谢。 - Jack Fox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接