C#中使用NUnit集成FsCheck

6

简述:我无法在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 测试一样运行它时,它最终是绿色的,即使我在标准输出上看到了。
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#不太熟悉,也看不懂下面的示例...)...(我已经盲目尝试了一些看起来有道理的东西,但从来没有得到过红色的测试结果)

如果能给我任何帮助,让我让这个测试变成红色,我将不胜感激!


尝试使用 Prop.ForAll(revRevIsOrig).QuickCheckThrowOnFailure(); - Nkosi
3个回答

7

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

太棒了:它完全按照我的预期工作!非常感谢! - gturri

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的答案现在更好,但我认为它将在未来得到修复。


来自FsCheck的github示例。请问您能分享一个链接吗? - Colonel Panic
https://github.com/fscheck/FsCheck/tree/master/examples/FsCheck.CSharpExamples - xneg

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 (除了我的.NET Core 3.1测试项目中的NUnit3TestAdapterMicrosoft.NET.Test.Sdk)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接