Reputation: 12434
This SO answer shows code which should cause an Xunit theory test to run multiple times with this method attribute applied:
[Theory]
[Repeat(3)]
public void MyTest()
{
// test code here
}
The Repeat()
attribute is defined as:
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);
}
}
The use case for this is to cause Xunit to run a test theory multiple times, until the data has been exhausted. For example, when the tests to be run are defined by externally-drawn data rather than specifically coded number of methods.
Unfortunately, the error this produces is:
[xUnit.net 00:00:00.55] Basic: Skipping test case with duplicate ID '071bf13109c976bcd6c61a7afa145a7a1cdb8e0a' ('Basic.Tests.MyTest()' and 'Basic.Tests.MyTest()')
[xUnit.net 00:00:00.55] Basic: Skipping test case with duplicate ID '071bf13109c976bcd6c61a7afa145a7a1cdb8e0a' ('Basic.Tests.MyTest()' and 'Basic.Tests.MyTest()')
Is there a way around this?
I have tried overriding the Skip
property but either I could not find the right value for it to return or it did not have the desired effect.
[EDIT] In response to the accepted answer by @peterszabo my code now looks like this:
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)
{
var list = new List<object[]>();
for (var i=1; i<=10; i++)
list.Add(new object[] {i});
return list as IEnumerable<object[]>;
}
}
It is the content of the object[]
in each list.Add()
which will change.
Upvotes: 2
Views: 1472
Reputation: 137
There is no variance to the input of the test. Your attribute is returning an empty object array, and your theory has no parameters, so you're basically trying to run the same test over and over again. So it gets skipped after the first execution.
If your tests' input data is
defined by externally-drawn data
then what you may want to try is let your DataAttribute
read the external datasource and yield results from it. Then you can receive this data as parameters of your [Theory]
method.
You can see an example of using a JSON file as an external data source for test theories on Andrew Lock's blog here.
Upvotes: 3