我创建了一个生成器来生成具有相同长度的int列表,并测试zip和解压缩的属性。运行测试我偶尔收到错误
错误:System.ArgumentException:list2 比 list1 短 1 个元素
但这不应该因为我的发电机而发生。
我得到了三倍的测试100%通过,然后是上面的错误。为什么?似乎我的发电机无法正常工作。
let samelength (x, y) =
List.length x = List.length y
let arbMyGen2 = Arb.filter samelength Arb.from<int list * int list>
type MyGenZ =
static member genZip() =
{
new Arbitrary<int list * int list>() with
override x.Generator = arbMyGen2 |> Arb.toGen
override x.Shrinker t = Seq.empty
}
let _ = Arb.register<MyGenZ>()
let pro_zip (xs: int list, ys: int list) =
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs = List.length ys)
do Check.Quick pro_zip
你的代码,正如所写的,对我有用。所以我不确定到底出了什么问题,但我可以给你一些有用的(希望是!(提示。
首先,尽量不使用注册机制,而是使用 Prop.forAll
,如下所示:
let pro_zip =
Prop.forAll arbMyGen2 (fun (xs,ys) ->
(xs, ys) = List.unzip(List.zip xs ys)
|> Prop.collect (List.length xs))
do Check.Quick pro_zip
请注意,我还更改了Prop.collect
调用以收集列表的长度,这提供了更有趣的输出。事实上,您的属性已经检查列表的长度是否相同(尽管是隐式的(,因此如果不是,测试将失败并显示反例。
Arb.filter
将现有Arbitrary
(即生成器和过滤器(转换为新Arbitrary
。换句话说,arbMyGen2
有一个可以工作的收缩函数(即只返回长度相等的较小列表对(,而genZip()
你扔掉收缩器。简单地写就好
type MyGenZ =
static member genZip() = arbMyGen2
相反。