Data driven test in NUnit with csv source data

Tim Abell · May 23, 2011

I wanted to test a date parser across a large range of values so wanted a simple test harness to test all the values.

The test framework options around c# / .net seem to be:
<ul><li>MSTest - can do csv via jet, but can’t do inline test data which is something I also want.</li><li>NUnit - can do inline data driven test data (with the TestCase(data…) attribute), and has support for extending this via the TestCaseSource attribute.</li><li>xUnit - confusing (aka flexible), doesn’t seem to get me to my end result any faster after a bit of searching around.</li></ul>I’ve used NUnit and combined TestCaseSource with a simple wrapper class around the csv parsing library

To get this to work:
<ul><li>Save your csv file in your test project</li><li>add the file to your project (in visual studio 2008 in this case)</li><li>right-click on the csv file in solution explorer, click properties, change “Copy to Output Directory” to “Copy Always”</li><li>download the binaries (dlls) for csv reader from code project, add a reference to this in your test project</li><li>add a private method to your test class for reading the csv file and returning an enumarable (see code below)</li><li>add the TestCaseSource attribute to your test method(s) that you want to use the csv data, referencing your new IEnumerable method (see code below)</li></ul>

<pre>using System.Collections.Generic;
using System.IO;
using LumenWorks.Framework.IO.Csv;
using NUnit.Framework;

namespace mytests
{
class MegaTests
{
[Test, TestCaseSource("GetTestData")]
public void MyExample_Test(int data1, int data2, int expectedOutput)
{
var methodOutput = MethodUnderTest(data2, data1);
Assert.AreEqual(expectedOutput, methodOutput, string.Format("Method failed for data1: {0}, data2: {1}", data1, data2));
}

private int MethodUnderTest(int data2, int data1)
{
return 42; //todo: real implementation
}

private IEnumerable<int[]> GetTestData()
{
using (var csv = new CsvReader(new StreamReader("test-data.csv"), true))
{
while (csv.ReadNextRecord())
{
int data1 = int.Parse(csv[0]);
int data2 = int.Parse(csv[1]);
int expectedOutput = int.Parse(csv[2]);
yield return new[] { data1, data2, expectedOutput };
}
}
}
}
}
</pre>

references:
<ul><li>CodeProject.com - CsvReader</li><li>StackOverflow.com - Data-driven testing in NUnit</li><li>NUnit TestCaseSource</li><li>msdn ref, c# yield - for generating an IEnumerable.</li></ul>

Share: Tweet | LinkedIn
Suggest improvments: page source on github