4

TL;DR:我无法在 C# 中成功地将 FsCheck 与 NUnit 一起使用:或者:

  • 它在标准输出上告诉我测试失败但测试仍然显示为绿色
  • 它告诉我它没有找到要运行的任何测试
  • 或者我不明白如何在 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|]

第二步:测试无定论

所以我继续,找到了一些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 启动了测试,结果是 status inconclusive。一些日志告诉我:

无法运行测试:在“xxx.exe”中找不到合适的测试。任一程序集不包含测试或未找到合适的测试驱动程序

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

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

可悲的是,我不明白我实际上应该做什么(而且我对 F# 不够熟悉,无法理解下面的示例......)......(我盲目地尝试了一些随机的东西看起来他们可能有道理,但我从来没有以红色测试结束)

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

4

3 回答 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();
}
于 2017-11-15T17:03:45.957 回答
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 的答案更好,但我认为它总有一天会修复。

于 2017-11-18T14:02:34.103 回答
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(除了我的NUnit3TestAdaptertestproject )。Microsoft.NET.Test.Sdk.NET Core 3.1

于 2020-11-24T14:24:40.307 回答