FsCheck与C#中NUnit的集成



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|]

第二步:测试不确定

所以我继续,找到了一些文档,并注意到我应该使用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"中找不到合适的测试。程序集不包含测试,或者找不到正确的测试驱动程序

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

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

可悲的是,我不明白我应该做什么(我对F#不够熟悉,无法理解下面的例子…)…(我盲目地尝试了一些看起来有意义的随机东西,但我从未以红色测试告终)

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

尝试使用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();
}

将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现在的答案更好了,但我认为总有一天会解决的。

除了其他提到的选项外,您还可以通过使用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(除了我的.NET Core 3.1测试项目中的NUnit3TestAdapterMicrosoft.NET.Test.Sdk)。

最新更新