NUnit TestCaseSource

9.7k views Asked by At

I'm having a go with the TestCaseSource attribute. One problem: when the sourceName string is invalid, the test just gets ignored instead of failing. This would be really bad if the source method gets renamed, the sourceName string doesn't get updated, and then you lose the coverage that the test provided. Is there a way to change the behaviour of NUnit, so that the test fails if the sourceName is invalid?

3

There are 3 answers

0
LK- On

How about using nameof feature introduced in C#6

public static class TestCasesData 
{ 
  public static string[] TestStringsData() 
  {
       return new string[] {"TEST1", "TEST2"};
  }
}

[TestFixture]
public class MyTest
{
     [Test]
     [TestCaseSource(typeof(TestCasesData), nameof(TestCasesData.TestStringsData))]
     public void TestCase1(...)
     {
     }
}
0
Miłosz Wierzbicki On

I've looked how it work internally in NUnit. They just throws exception if particular source does not exists:

MemberInfo[] members = providerType.GetMember(
 providerName,
 MemberTypes.Field | MemberTypes.Method | MemberTypes.Property,
 BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

if (members.Length == 0)
 throw new Exception(string.Format(
  "Unable to locate {0}.{1}", providerType.FullName, providerName));

Later they catch it and mark particular ParameterSet (class which wraps test case source) as RunState.NotRunnable which will later be handled as Ignored test.

So, there is probably no way to change this behavior without changing NUnit code - which is btw available for download. You can also try to contact with NUnit team or just treat ignored test in the same way as failing ones:)

0
TrueWill On

This is resolved in NUnit 2.6.2. There is a new constructor for the attribute that takes a Type (which must implement IEnumerable); it "is recommended for use in preference to other forms because it doesn't use a string to specify the data source and is therefore more easily refactored." (From the documentation.)

This does require that your test runner supports the latest NUnit.

A very basic example (see the above documentation link for more details):

public class TestDataProvider : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        return new List<int>{ 2, 4, 6 }.GetEnumerator();
    }
}

[TestFixture]
public class MyTests
{
    [TestCaseSource(typeof(TestDataProvider))]
    public void TestOne(int number)
    {
        Assert.That(number % 2, Is.EqualTo(0));
    }
}