FsCheck与C中的NUnit集成

时间:2017-11-15 16:25:32

标签: c# unit-testing nunit fscheck

TL; DR:我无法在C#中成功使用FsCheck和NUnit:

  • 它告诉我stdout测试失败但测试仍然显示为绿色
  • 它告诉我它没有找到任何运行的测试
  • 或者我不明白如何在C#中申请我读过的文件

我认为一个虚拟但完整的例子会有所帮助...

(更多细节)

第一步:测试保持绿色

我安装了Nuget包FsCheck.NUnit(2.10.4),天真地试过:

[NUnit.Framework.Test]
public void SomeTest()
{
    // Note the subtle bug: I Reverse only once, because I want the test to fail
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    Prop.ForAll(revRevIsOrig).QuickCheck();
}

当我运行它时,因为我会运行任何NUnit测试,它会以绿色结束,即使我在stdout上看到

Falsifiable, after 3 tests (1 shrink) (StdGen (2129798881,296376481)):
Original:
[|-1; 0|]
Shrunk:
[|1; 0|]

第二步:测试不确定

所以我接着发现了一些doc,并注意到我应该使用Property代替Test。所以我将代码更改为

[FsCheck.NUnit.Property] // <-- the line that changed
public void SomeTest()
{
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    Prop.ForAll(revRevIsOrig).QuickCheck();
}

我从Visual启动了测试,结果是状态inconclusive。有些日志告诉我:

  

无法运行测试:在'xxx.exe'中找不到合适的测试。任何一个程序集都不包含任何测试或未找到正确的测试驱动程序

第3步:我注意到我不理解文档

当我重新阅读文档时,我注意到它说我的测试方法可以接受参数并且应该返回一个属性。我显然没有这样做,因为我什么也没有回来。

可悲的是,我不明白我应该做什么(我对F#不太熟悉以理解下面的例子......)...(我已经盲目地尝试了一些随机的东西,看起来他们可能有意义,但我从来没有结束红色测试)

我真的很感激任何帮助我把这个测试变成红色的指针!

3 个答案:

答案 0 :(得分:5)

尝试使用QuickCheckThrowOnFailure功能

  

QuickThrowOnFailure确保如果测试失败,则会引发包含必要信息的异常,以便跑步者知道测试失败。

[Test]
public void SomeTest() {
    // Note the subtle bug: I Reverse only once, because I want the test to fail
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    Prop.ForAll(revRevIsOrig).QuickCheckThrowOnFailure();
}

答案 1 :(得分:3)

将FsCheck与NUnit(来自FsCheck github示例)一起使用的另一种方法是

[FsCheck.NUnit.Property(Verbose = true)]
public void SomeTest()
{
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    return Prop.ForAll(revRevIsOrig);
}

但这种方式不会报告您测试失败的原因。所以Nkosi的答案现在更好了,但我认为它将在某一天得到解决。

答案 2 :(得分:0)

除了其他提到的选项之外,您还可以使用Property属性和正确的返回类型(为了清楚起见,我添加了名称空间)将此测试转变为基于属性的测试。

请注意将.ToProperty调用变成Property

[FsCheck.NUnit.Property]
public FsCheck.Property RevRev_IsOriginal(int[] xs)
{
    Func<bool> revRevIsOrig = () => xs.Reverse().Reverse().SequenceEqual(xs);
    return revRevIsOrig.ToProperty();
}

该框架将通过int[] xs方法参数生成测试数据。

这需要 nuget包 fscheckfscheck.nunit(在我的NUnit3TestAdapter测试项目中,除了Microsoft.NET.Test.Sdk.NET Core 3.1之外)。