C# FsCheck与NUnit在C中的集成#

C# FsCheck与NUnit在C中的集成#,c#,unit-testing,nunit,fscheck,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 th

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();
}
第二步:测试不确定

所以我继续,找到了一些,并注意到我应该使用
属性
,而不是
测试
。所以我把代码改成了

[FsCheck.NUnit.Property] // <-- the line that changed
public void SomeTest()
{
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    Prop.ForAll(revRevIsOrig).QuickCheck();
}
[FsCheck.NUnit.Property]//xs.Reverse().SequenceEqual(xs);
Prop.ForAll(revrevisiorig).QuickCheck();
}
我从Visual启动了测试,结果状态为
不确定
。一些日志告诉我:

无法运行测试:“xxx.exe”中找不到合适的测试。组件未包含测试或未找到正确的测试驱动程序

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

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

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


我真的很感激任何能帮助我得到这个红色测试的指针

尝试使用
QuickCheckThrowOnFailure
功能

QuickThrowOnFailure
确保如果测试失败,将引发包含必要信息的异常,以便运行者知道测试失败

[测试]
公共测试(){
//注意微妙的错误:我只反转一次,因为我希望测试失败
Func revrevisisorig=xs=>xs.Reverse().SequenceEqual(xs);
Prop.ForAll(revrevisiorig).QuickCheckThrowOnFailure();
}

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

[FsCheck.NUnit.Property(Verbose=true)]
公共测试()
{
Func revrevisisorig=xs=>xs.Reverse().SequenceEqual(xs);
返回道具ForAll(修订版);
}

但这种方法不会报告测试失败的原因。因此,Nkosi现在的答案更好了,但我认为它有一天会被修复。

除了上面提到的其他选项之外,您可以通过使用
属性和正确的返回类型(为了清晰起见,我已经包含了名称空间)将此测试转换为基于属性的测试

请注意
.ToProperty
调用以将其转换为
属性

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

[FsCheck.NUnit.Property]
公共FsCheck.Property RevRev_IsOriginal(int[]xs)
{
Func revrevisisorig=()=>xs.Reverse().Reverse().SequenceEqual(xs);
return revrevisisorig.ToProperty();
}
框架将通过
int[]xs
方法参数生成测试数据


这需要nuget包
fscheck
fscheck.nunit
(除了
NUnit3TestAdapter
Microsoft.NET.Test.Sdk
在我的
.NET Core 3.1
testproject中)。

Try
Prop.ForAll(revrevrevrevrevisiorig.QuickCheckThrowOnFailure()棒极了:它完全按照我的预期工作!谢谢!“从FsCheck github示例”请分享一个链接好吗?如果仍然相关
[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.Property(Verbose = true)]
public void SomeTest()
{
    Func<int[],bool> revRevIsOrig = xs => xs.Reverse().SequenceEqual( xs );
    return Prop.ForAll(revRevIsOrig);
}
[FsCheck.NUnit.Property]
public FsCheck.Property RevRev_IsOriginal(int[] xs)
{
    Func<bool> revRevIsOrig = () => xs.Reverse().Reverse().SequenceEqual(xs);
    return revRevIsOrig.ToProperty();
}