【发布时间】:2020-09-23 14:09:44
【问题描述】:
我正在尝试使用 fscheck 实现一个生成器和一个收缩器,这将产生两个不为空且彼此不同的字符串。为此,我使用以下代码:
let nonWhiteSpaceString s =
not (String.IsNullOrWhiteSpace s) && not (String.exists ((=) '\000') s)
type DifferentNonWhiteSpace = | DifferentNonWhiteSpace of NonWhiteSpaceString*NonWhiteSpaceString
type DifferentNonWhiteSpaceGen =
static member DifferentNonWhiteSpace() =
let generator =
generate<String>
|> Gen.two
|> Gen.filter (fun (a,b) -> nonWhiteSpaceString a && nonWhiteSpaceString b && a<>b )
|> Gen.map (fun (a,b) -> DifferentNonWhiteSpace((NonWhiteSpaceString a),NonWhiteSpaceString(b)))
let shrinker (DifferentNonWhiteSpace(a,b)) =
let seqA = a.Get.ToCharArray()
|> shrink
|> Seq.map String
b.Get.ToCharArray()
|> shrink
|> Seq.map String
|> Seq.map2 (fun x y -> if x <> y then Some(DifferentNonWhiteSpace(NonWhiteSpaceString x,NonWhiteSpaceString y)) else None) seqA
|> Seq.choose id
fromGenShrink (generator,shrinker)
我在测试中使用它如下:
testProperty "calculate Xml against different Prefix should produce youpi" <| fun (DifferentNonWhiteSpace(prefix1,prefix2)) ->
let xml1 = createXml <| changePrefix prefix1
let xml2 = createXml <| changePrefix prefix2
let actual = calculate xml1 xml2
Expect.equal actual Youpi "return youpi"
生成器看起来不错,但收缩器并没有达到我的预期:
1 次测试后失败。参数: 不同的NonWhiteSpace (NonWhiteSpaceString "K",NonWhiteSpaceString "▲") 缩小 3 倍至: 不同的NonWhiteSpace (NonWhiteSpaceString "a",NonWhiteSpaceString "a") 结果: 例外 Expecto.AssertException: return Bouh.
我不应该在缩小的数据中有相同的值:
DifferentNonWhiteSpace (NonWhiteSpaceString "a",NonWhiteSpaceString “一”)
谁能指出我做错了什么?
谢谢
[编辑] 实际上,我的生成器也有问题。
Failed after 11 tests. Parameters:
DifferentNonWhiteSpace (NonWhiteSpaceString "v",NonWhiteSpaceString "v")
Result:
Exception
Expecto.AssertException: return Bouh.
很奇怪……
【问题讨论】:
-
这可能是 FsCheck 中的一个错误。如果您将其发布到 github 上的 FsCheck repro,您可能会更幸运。我自己使用 FsCheck 已经有一段时间了,所以我可能无法帮助您解决这个具体案例。
-
我将在 github 中提出问题。谢谢你的评论
-
我认为 FsCheck 只是没有选择您的自定义
Arbitrary实例。我对 expecto 不太熟悉 - 是否有testProperty或类似的参数允许您传入Arbitrary或类似的参数?如果你喜欢我也可以用“纯”FsCheck 中的一个例子来回答。 -
testPropertyWithConfig我认为应该可以工作,配置希望与 FsCheck 相同,因此有一个字段用于传入具有覆盖的类型,即尝试testPropertyWithConfig { FsCheckConfig.defaultConfig with Arbitrary = typeof<DifferentNonWhiteSpaceGen> } -
就是这样。我是多么愚蠢。我忘了使用“testPropertyWithConfig config”来使用正确的 abitraries 而不是“testProperty”