首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FsCheck DataGen为空

FsCheck DataGen为空
EN

Stack Overflow用户
提问于 2015-01-05 20:32:54
回答 1查看 175关注 0票数 2

我正在尝试通过一个FsCheck的例子来研究一种带有歧视工会的类型,以便为我们更大的项目建立最佳实践。现在,我从我的生成器得到零,我不知道为什么。在下面的代码中,DataGen.containerGenerator为null。

代码语言:javascript
复制
namespace Container
open System
open Xunit
open FsCheck

module ContainerLibrary = 
    type [<Measure>] oz

    type Container = 
        | Cup of Common
        | Bowl of Common
    and Common = 
        { Volume    :decimal<oz>
          Weight    :decimal}

module DataGen = 
    type Generators = 
        static member arbVolume = 
            FsCheck.Gen.choose (1, 16)
            |> FsCheck.Gen.map(fun x -> (decimal x / 8.0M) * 1.0M<ContainerLibrary.oz>)
            |> FsCheck.Arb.fromGen

    FsCheck.Arb.register<Generators>() |> ignore

    let bowlGenerator = 
        FsCheck.Gen.map2 (fun a b -> ContainerLibrary.Bowl( { Volume = a 
                                                              Weight = b})) 
                         (Generators.arbVolume.Generator) 
                         (FsCheck.Arb.generate<decimal>)
    let cupGenerator =
        FsCheck.Gen.map2 (fun a b -> ContainerLibrary.Cup( { Volume = a 
                                                             Weight = b})) 
                         (Generators.arbVolume.Generator) 
                         (FsCheck.Arb.generate<decimal>)

    let containerGenerator =
        Gen.oneof [bowlGenerator; cupGenerator]

module Tests =
    [<Fact;>]
    let ``01 : Containers must be no more than 20 oz`` () =
        //Is this the best way to get one of something?
        let c = FsCheck.Gen.sample 0 1 DataGen.containerGenerator |> Seq.head
        Assert.NotNull (c)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-06 09:23:34

当我运行它时,它看起来并不是空的,即使我得到了更多的值。您使用的是哪个版本的FsCheck?

代码语言:javascript
复制
[<Fact;>]
let ``01 : Containers must be no more than 20 oz`` () =
    //Is this the best way to get one of something?
    Gen.sample 0 100 DataGen.containerGenerator |> Seq.iter(fun c -> printf "%A" c; Assert.NotNull (c))

在任何情况下,对于你正在做的事情,有几件事情需要注意。

  • FsCheck使用反射来注册生成器;反射不能看到度量类型参数的类型。因此,对于所有小数,Arb.register实际上都会覆盖十进制生成器。
  • 不知怎么的FsCheck。你所使用的资格令人困惑,智力感无止境。
  • Gen.sample是测试生成器的一种合理方法,但我主要是在交互式设置中使用它;如果您经历了设置测试的麻烦,我倾向于使用FsCheck内置的测试用例观察功能。参见此处的“观察测试用例分布”:https://fsharp.github.io/FsCheck/Properties.html
  • 在模块init中使用Arb.register有点易碎,这取决于F#中的模块初始化规则来注册生成器。如果您正在使用Xunit,最好使用内置集成来减少这方面不可避免的挫折。

考虑到以下几点,我重写了您的示例:

代码语言:javascript
复制
module DataGen = 

open ContainerLibrary

//can't really register this one because of the measure, would override all decimal generatos
let volumeGenerator = 
        Gen.choose (1, 16)
        |> Gen.map(fun x -> (decimal x / 8.0M) * 1.0M<ContainerLibrary.oz>)

let commonGenerator =
    Gen.map2 (fun a b -> { Volume = a 
                           Weight = b})
                     (volumeGenerator) 
                     (Arb.generate<decimal>)

//in case you like applicative style, otherwise completely equivalent
let commonGeneratorAlternative =
    (fun a b -> { Volume = a; Weight = b}) <!> volumeGenerator <*> Arb.generate<decimal>

let bowlGenerator = Gen.map Bowl commonGenerator
let cupGenerator = Gen.map Cup commonGenerator

let containerGenerator =
    Gen.oneof [bowlGenerator; cupGenerator]

type Generators =
    static member Container() = containerGenerator |> Arb.fromGen

module Tests =
open FsCheck.Xunit
open ContainerLibrary

//use PropertyAttribute from FsCheck.Xunit
//use the defined container generator - can also move this to module level
//other ways to parametrize
[<Property(Arbitrary=[|typeof<DataGen.Generators>|])>]
//thanks to PropertyAttribute can now just take container as argument
let ``01 : Containers must be no more than 20 oz`` (container:Container) =
    match container with
    | Cup common
    | Bowl common -> common.Volume <= 20.0M<oz>
    |> Prop.collect container //see the generated values in the output

它输出的输出类似于:

好的,通过了100次测试。

1%杯{体积= 2.0M;重量=-0.00002213609288587415609M;}1%杯{体积= 1.8750M;重量= 922337.20325598085121M;}等

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27787430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档