2

我正在尝试使用 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

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

4

2 回答 2

4

它似乎与FsCheck GitHub 上描述的已知问题有关。

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

要解决问题:

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

  2. 单击“添加参考”以再次添加它,转到“程序集”->“扩展”并添加与其他项目中使用的版本相同的 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>
    
于 2016-01-18T22:26:24.523 回答
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 版本的引用重定向到指定的较新版本。

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>在您的 .fsproj 中使用可以自动生成此类绑定重定向。有关使用的更多详细信息,请参阅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.

于 2016-01-17T23:32:35.113 回答