我有一些方法依赖于一些随机计算来提出建议,我需要多次运行Fact以确保没问题。
我可以在我要测试的事实中包含一个for循环,但是因为有几个测试我想要这样做,所以我查找了一个更干净的方法,类似于junit中的重复属性:http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly-without-loops/ < / p>
我可以在xunit中轻松实现这样的功能吗?
答案 0 :(得分:25)
你必须创建一个新的DataAttribute
来告诉xunit多次运行相同的测试。
这是一个遵循junit相同概念的示例:
public class RepeatAttribute : DataAttribute
{
private readonly int _count;
public RepeatAttribute(int count)
{
if (count < 1)
{
throw new ArgumentOutOfRangeException(nameof(count),
"Repeat count must be greater than 0.");
}
_count = count;
}
public override IEnumerable<object[]> GetData(MethodInfo testMethod)
{
return Enumerable.Repeat(new object[0], _count);
}
}
使用此代码后,您只需将Fact
更改为Theory
并使用Repeat
,如下所示:
[Theory]
[Repeat(10)]
public void MyTest()
{
...
}
答案 1 :(得分:2)
具有相同的要求,但是可接受的答案代码没有重复测试,因此我将其调整为:
public sealed class RepeatAttribute : Xunit.Sdk.DataAttribute
{
private readonly int count;
public RepeatAttribute(int count)
{
if (count < 1)
{
throw new System.ArgumentOutOfRangeException(
paramName: nameof(count),
message: "Repeat count must be greater than 0."
);
}
this.count = count;
}
public override System.Collections.Generic.IEnumerable<object[]> GetData(System.Reflection.MethodInfo testMethod)
{
foreach (var iterationNumber in Enumerable.Range(start: 1, count: this.count))
{
yield return new object[] { iterationNumber };
}
}
}
虽然在前面的示例中使用了Enumerable.Repeat,它只能运行1次测试,但是xUnit不会以某种方式重复测试。他们可能在不久前改变了某些东西。
通过更改为foreach
循环,我们可以重复每个测试,但我们还提供了“迭代次数”。
在测试功能上使用它时,您必须向测试功能中添加参数,并将其装饰为Theory
,如下所示:
[Theory(DisplayName = "It should work")]
[Repeat(10)]
public void It_should_work(int iterationNumber)
{
...
}
这适用于xUnit 2.4.0。
我创建了一个NuGet package以便在任何人感兴趣的情况下使用。
答案 2 :(得分:1)
我知道这是一个旧线程,但是如果需要重复几次测试,可以使用以下技巧:
首先,创建一些虚拟数据:
public static IEnumerable<object[]> DummyTestData()
{
yield return new object[] { 0 };
yield return new object[] { 1 };
yield return new object[] { 2 };
yield return new object[] { 3 };
}
然后使用伪数据来强制对每个向量运行测试。在这种情况下,同一测试将被调用4次(但实际上并未使用伪数据):
private static int _counter = 0;
[Theory]
[MemberData(nameof(DummyTestData))]
public void SomeTest(int dummyParam) // dummyParam is unused
{
_counter+= 1;
DoSomething();
Assert.True(...);
}
与创建新属性相比,我发现这种方法非常有用且省事。
当然,如果您需要将重复次数设为可参数化的话,这不是一个好的解决方案(尽管我确信有人可以建议使我的解决方案参数化的方法:-)。
答案 3 :(得分:0)
少量迭代的最简单方法:使其成为理论而不是事实。 为每次迭代插入一行 [InlineData]。
using Xunit;
namespace MyUnitTests
{
public class Class1
{
[Theory]
[InlineData]
[InlineData]
public void TestThis()
{
// test code here
}
}
}
使用 XUnit 2.4.1 测试