FsCheck.xUnit:从另一个程序集测试类型

时间:2016-01-17 22:11:31

标签: f# xunit fscheck

我试图用FsCheck和xUnit进行我的第一次测试。我有以下设置:

  • 具有单个文件的F#类库

    namespace Lib
    type ABC = A | B | C
    
  • 一个名为Tests的项目,其中包含对单个文件的FsCheck.xUnit NuGet包的引用:

    module LibTests    
    open FsCheck.Xunit
    open Lib    
    [<Property>]
    let ``ABC is always A`` v =
      v = A
    

当我运行项目时(使用VS或控制台运行程序),我收到以下错误:

System.Exception : The type Lib.ABC is not handled automatically by FsCheck. 
Consider using another type or writing and registering a generator for it

如果我将我的类型移动到Tests组件,一切正常(测试失败)。我如何测试外部类型?

2 个答案:

答案 0 :(得分:4)

它似乎与已知问题described on FsCheck GitHub有关。

基本上,FsCheck NuGet包依赖于旧版本的FSharp.Core库。旧版本被引用,这使得测试代码与被测系统不兼容。

解决问题:

  1. 安装FsCheck NuGet包后,转到测试项目引用并删除对旧版FSharp.Core的引用(在我的情况下为4.3.1.0)。

  2. 点击“添加参考”再次添加,转到“装配” - &gt;扩展并添加与您的其他项目中使用的版本相同的FSharpCore,在我的情况下为 4.4.0.0

  3. 使用以下内容将App.config文件添加到测试项目中:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="4.3.1.0" newVersion="4.4.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    

答案 1 :(得分:3)

首先,当我运行这个时,我确实会对你产生不同的行为。我的测试项目的一个示例结果:

  

结果消息:FsCheck.Xunit.PropertyFailedException:Falsifiable,   经过4次测试(0缩小)(StdGen(196938613,296107830)):原文:B

这是有道理的,因为fscheck应该能够通过反射自动为受歧视的联合类型(例如ABC)创建生成器,请参阅:https://fscheck.github.io/FsCheck/TestData.html

因此,我建议您检查所有正确安装的软件包并完全更新。

我安装了:

  • FsCheck(v2.2.4)
  • FsCheck.Xunit(v2.2.4)
  • xunit(v2.1.0)

<强> FSharp.Core

安装引用FSharp.Core的nuget软件包时要小心,因为它们通常使用覆盖项目设置的特定版本分发。

如果发生这种情况,请从packages.config文件中删除FSharp.Core,删除项目中对FSharp.Core的引用,并从程序集列表中将其替换为所需的FSharp.Core版本。您可以在扩展名下找到FSharp.Core。

您还可以使用app.config文件中的绑定重定向将旧版FSharp.Core版本的引用重定向到指定的较新版本。

在.fsproj中使用<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>可以自动生成此类绑定重定向。有关使用情况的详细信息,请参阅https://fsharp.github.io/2015/04/18/fsharp-core-notes.html

<强>发电机

您所拥有的错误消息引用了一个功能fscheck,您可以在其中指定如何为属性测试创建类型的任意实例。自定义生成器的示例:

type MyGenerators =
    static member ABC() =
        {new Arbitrary<ABC>() with
            override x.Generator = gen { return A; } // generator that creates only A
            override x.Shrinker t = Seq.empty }

然后我可以使用这个生成器检查我的属性:

[<Property(Arbitrary=[|typeof<MyGenerators>|])>]
static member ``ABC is always A`` v =
    v = A

此测试现在总是通过,因为我总是指定生成器创建A