强制FsCheck生成NonEmptyString以区分string类型的union字段

时间:2017-08-15 13:49:21

标签: testing f# fscheck

我尝试使用FsCheck实现以下行为:我想创建一个生成MyUnion类型实例的生成器,每个字符串字段都为非null /空

type MyNestedUnion =
    | X of string
    | Y of int * string

type MyUnion =
    | A of int * int * string * string
    | B of MyNestedUnion

我的真实' type比MyUnion大得多/深,并且FsCheck能够生成一个没有任何问题的实例,但是union case的字符串字段有时是空的。 (例如,它可能会生成B (Y (123, ""))

或许还有一些明显的方法可以将FsCheck' NonEmptyString与其生成的任意联合类型的支持结合起来,而这种方式是我错过的?

正确方向的任何提示/指示都非常感谢。

谢谢!

1 个答案:

答案 0 :(得分:5)

这违反了基于属性的测试(因为你明确地阻止了生成有效的测试用例),但你可以将非空字符串生成器连接起来用于所有字符串:

type Alt =
    static member NonEmptyString () : Arbitrary<string> =
        Arb.Default.NonEmptyString()
        |> Arb.convert
            (fun (nes : NonEmptyString) -> nes.Get)
            NonEmptyString.NonEmptyString

Arb.register<Alt>()

let g = Arb.generate<MyUnion>

Gen.sample 1 10 g

请注意,由于映射是全局的,因此您需要在测试后重新注册默认生成器。

更多的书籍解决方案是使用默认的派生生成器,然后过滤包含无效字符串的值(即使用==>),但您可能会发现它对于特别深的嵌套类型不可行。