All of the built-in attributes allow for data to be provided programmatically, but NUnit does not have any attributes that fetch the data from a file or other external source.
The Test attribute is one way of marking a method inside a TestFixture class as a test. It is normally used for simple (non-parameterized) tests but may also be applied to parameterized tests without causing any extra test cases to be generated.
If you add a second parameter with the Values attribute, for per value of the first parameter, NUnit will add a test for every value of the second parameter. Another way to avoid having to write duplicate tests when testing the same behaviour with different inputs is to use TestCase attribute on the test itself.
The property TestName
has a support in NUnit 3 for string formatting.
Here's an example usage:
private static IEnumerable TestData()
{
TestCaseData data;
data = new TestCaseData(new Foo("aaa"))
.SetName("case 1 {m}");
yield return data;
data = new TestCaseData(new Foo("bbb"));
yield return data;
}
Will generate the following out put:
As you can see the test names the of the first case contains the custom prefix + the method name.
Use this link for more information about NUnit's string formating capability.
2 classes are resposable for this action NUnitTestCaseBuilder (line 83) and TestNameGenerator
method .GetDisplayName()
.
This isn't a perfect answer, but the best solution I've found so far is that I create a wrapper for the TestData emitter that gets passed in as the TestCaseSource.
[Test, TestCaseSource("TestData_Test1")]
public void Test1(Foo foo)
{
// test 1
}
[Test, TestCaseSource("TestData_Test2")]
public void Test2(Foo foo)
{
// test 2
}
private static IEnumerable TestData_Test1()
{
return TestData_Base("Test1");
}
private static IEnumerable TestData_Test2()
{
return TestData_Base("Test2");
}
private static IEnumerable TestData_Base(string testName)
{
TestCaseData data;
data = new TestCaseData(new Foo("aaa"));
data.SetName(string.Format("{0}(Foo=aaa)", testName));
yield return data;
data = new TestCaseData(new Foo("bbb"));
data.SetName(string.Format("{0}(Foo=bbb)", testName));
yield return data;
}
This means that my tests are now emitted from NCrunch, TeamCity, etc as
Test1(Foo=aaa)
Test1(Foo=bbb)
Test2(Foo=aaa)
Test2(Foo=bbb)
Which is at least better than the completely useless default.
Well, if you are lucky to use .NET 4.5, you can use the [CallerMemberName] attribute on the last argument of the constructor of a new TestCaseSourceEx attribute extending TestCaseSource, which will give you the test method name inside the attribute constructor.
Here's a working sample:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestCaseSourceEx : TestCaseSourceAttribute
{
public TestCaseSourceEx(Type sourceType, string sourceName, [CallerMemberName] string methodName = null)
: base(sourceType, sourceName)
{
}
public TestCaseSourceEx(string sourceName, [CallerMemberName] string methodName = null)
: base(sourceName)
{
}
}
[TestFixture]
public class SampleTests
{
public IEnumerable List = new[] { new string[] { "test-username", "test-password" } };
[Test, TestCaseSourceEx("List")]
public void SampleTests_LoginTest(string username, string password)
{
}
}
After long googling i've found my solution which was alot easier than those posted above:
1st. In test case I've added another parameter: string testName:
[Test, TestCaseSource("TestData")]
public void Test1(string testName, Foo foo)
{
// test 1
}
[Test, TestCaseSource("TestData")]
public void Test2(String testName, Foo foo)
{
// test 2
}
2nd. in TestCaseData I've added another parameter which shows unique property of Foo object eg. name
private static IEnumerable TestData()
{
TestCaseData data;
Foo data1 = new Foo("aaa");
data = new TestCaseData(data1.name, data1);
yield return data;
Foo data2 = new Foo("bbb");
data = new TestCaseData(data2.name, data2);
yield return data;
}
In NUnit runner the result are displayed like this:
Namespace.That.Is.Very.Long.TestClass.Test1("aaa", Namespace.That.Is.Very.Long.Foo)
Namespace.That.Is.Very.Long.TestClass.Test1("bbb", Namespace.That.Is.Very.Long.Foo)
This makes tests separate in output window, while i'm still able to see exactly which test is being runned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With