【问题标题】:FsCheck lazy generatorsFsCheck 惰性生成器
【发布时间】:2020-01-03 19:13:53
【问题描述】:

我在测试中生成数据时遇到问题。

    testProperty "calculate Operation against different operations should increase major" <| fun  operationIdApi operationIdClient summaryApi summaryClient descriptionApi descriptionClient   -> 
    ( notAllEqual [
            fun () -> assessEquality <| StringEquals(operationIdApi, operationIdClient)
            fun () -> assessEquality <| StringEquals(summaryApi , summaryClient)
            fun () -> assessEquality <| StringEquals(descriptionApi, descriptionClient)
        ]) ==> lazy (
        let operationClient = createOpenApiOperation operationIdClient summaryClient descriptionClient
        let operationAPI = createOpenApiOperation operationIdApi summaryApi descriptionApi
        let actual = calculate operationAPI operationClient
        Expect.equal actual (Fact.Semver.IncreaseMajor) "return IncreaseMajor"
    )

实际测试的代码是:

 semver {
            if operationAPI.OperationId<> operationClient.OperationId then yield! IncreaseMajor
            if operationAPI.Summary <> operationClient.Summary then yield! IncreaseMajor
        }

当产生的数据是相同的OperationId,相同的摘要和不同的描述时,测试应该失败。 但事实并非如此,它让我创建了自己的生成器,或者至少尝试这样做:

我希望我的测试写成这样:

testProperty "calculate Operation against different operations should increase major" <| fun  (operationId:ElementSet<string>)  (summary:ElementSet<string>)   -> 

因此我相应地创建了一个类型:

type ElementSet<'a> =
    | Same of 'a
    | Different 

以及这种类型的生成器:

let setGen<'a> =
    Gen.oneof [
            gen { 
                let! v = Arb.generate<'a>
                return Same(v)
            }
            gen { return Different}
    ]

type ElementSetGenerator =
    static member ElementSet() = 
        Arb.fromGen setGen<'a>

do Arb.register<ElementSetGenerator>() |> ignore

然后我试图提取数据来构造我的对象:

let createOpenApiOperation operationId summary=
let pi  = OpenApiOperation(OperationId=operationId.Get, Summary=summary.Get)    
pi

Get 方法还不存在,所以我打算通过向我的 ElementSet 添加一个成员来实现它:

type ElementSet<'a> =
    | Same of 'a
    | Different 
    with member this.Get = 
        match this with
            | Same s -> s
            | Different ->  Arb.generate<'a>// some random generation here 

这就是我卡住的地方。当我提取数据时,我很想在这里获得一些随机性。我想知道这是否是正确的方法,还是我应该早点回答这个问题?

感谢您的意见。

【问题讨论】:

    标签: f# fscheck


    【解决方案1】:

    我想我找到了,答案是一开始就处理它:

    let setGen<'a when 'a:equality>   =
        Gen.oneof [
                gen { 
                    let! v = Arb.generate<'a>
                    return Same(v)
                }
                gen { 
                    let! x,y  =
                        Arb.generate<'a>
                        |> Gen.two
                        |> Gen.filter (fun (a,b)-> a <> b)
    
                    return Different(x,y)
                }
        ]
    

    然后使用两个 getter 来访问值:

    type ElementSet<'a> when 'a:equality=
        | Same of 'a
        | Different of 'a*'a
        with member this.Fst =  match this with | Same s -> s | Different (a, b)->  a
             member this.Snd =  match this with | Same s -> s | Different (a, b)->  b
    

    这样我可以在我的测试中访问值:

     testProperty "calculate Operation against different operations should increase major" <| fun  (operationId:ElementSet<NonWhiteSpaceString>)  (summary:ElementSet<NonWhiteSpaceString>) (description:ElementSet<NonWhiteSpaceString>)   -> 
      let operationClient = createOpenApiOperation operationId.Fst summary.Fst description.Fst
      let operationAPI = createOpenApiOperation operationId.Snd summary.Snd description.Snd
      let actual = calculate operationAPI operationClient
      Expect.equal actual (Fact.Semver.IncreaseMajor) "return IncreaseMajor"
    

    为了记录,我创建了我的存根,如下所示:

    let createOpenApiOperation (operationId:NonWhiteSpaceString) (summary:NonWhiteSpaceString) (description:NonWhiteSpaceString)=
    let pi  = OpenApiOperation(OperationId=operationId.Get, Summary=summary.Get, Description=description.Get)    
    pi
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2016-09-13
      • 2014-12-17
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多