[ACCEPTED]-Data-driven testing in NUnit?-data-driven-tests

Accepted answer
Score: 12

I got csv based data driven testing in NUnit 7 working as follows:

Use the csv reader from code project, wrapped up 6 in a private method returning IEnumerable 5 in your test class, and then reference this 4 with a TestCaseSource attribute on your 3 test cases. Include your csv file in your 2 project and set "Copy to Output Directory" to "Copy Always".

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 };
                }
            }
        }
    }
}

original 1 post at: http://timwise.blogspot.com/2011/05/data-driven-test-in-nunit-with-csv.html

Score: 10

I would look at the parameterized tests documentation in NUnit 2.5 and see if you can 9 do something like what you're doing there. I 8 do not recall NUnit having a built-in CSV 7 reading attribute to drive parameterized 6 tests. There may be a community plug-in 5 somewhere though.

I should also point out 4 that if you are just looking for non-MS 3 Unit Testing framework libraries to help 2 you out, xUnit.net does have this functionality. Check 1 out this blog post from Ben Hall

Score: 4

Here is another example very similar to 9 Tim Abell's however not using a framework 8 for the CSV reader and showing the specifics 7 of the test. Note when you use the TestCaseAttribute 6 the TestAttribute can be omitted.

        [TestCaseSource("GetDataFromCSV")]
    public void TestDataFromCSV(int num1,int num2,int num3)
    {
        Assert.AreEqual(num1 + num2 ,num3);
    }

    private IEnumerable<int[]> GetDataFromCSV()
    {
        CsvReader reader = new CsvReader(path);
        while (reader.Next())
        {
            int column1 = int.Parse(reader[0]);
            int column2 = int.Parse(reader[1]);
            int column3 = int.Parse(reader[2]);
            yield return new int[] { column1, column2, column3 };
        }
    }


public class CsvReader : IDisposable
{
    private string path;
    private string[] currentData;
    private StreamReader reader;

    public CsvReader(string path)
    {
        if (!File.Exists(path)) throw new InvalidOperationException("path does not exist");
        this.path = path;
        Initialize();
    }

    private void Initialize()
    {
        FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
        reader = new StreamReader(stream);
    }

    public bool Next()
    {
        string current = null;
        if ((current = reader.ReadLine()) == null) return false;
        currentData = current.Split(',');
        return true;
    }

    public string this[int index]
    {
        get { return currentData[index]; }
    }


    public void Dispose()
    {
        reader.Close();
    }
}

CSV Data:

10,200,210 20,190,210 30,180,210 40,170,210 50,160,210 60,150,210 70,140,210 80,130,210 90,120,210 100,110,210

Note: The 5 3rd column is a sum of the first two columns 4 and this will be asserted in the unit test.

Results:

results

Find 3 below an alternative using TestCaseData 2 objects and setting a return type (which 1 off-course is mandatory)

        [TestCaseSource("GetDataFromCSV2")]
    public int TestDataFromCSV2(int num1, int num2)
    {
        return num1 + num2;
    }

    private IEnumerable GetDataFromCSV2()
    {
        CsvReader reader = new CsvReader(path);
        while (reader.Next())
        {
            int column1 = int.Parse(reader[0]);
            int column2 = int.Parse(reader[1]);
            int column3 = int.Parse(reader[2]);
            yield return new TestCaseData(column1, column2).Returns(column3);
        }
    }
Score: 0

MS Test provides a mechanism to have your 17 test data from different sources. However 16 this is not available out of the box from 15 NUnit.

I am in favor of using separating 14 the data and code for tests that are of 13 some considerable size. When I separate 12 both, my expectation are 1. Readability 11 of test data 2. Test data should be easy 10 to modify 3. The unit tests should run comfortably 9 in local and build environment

The JsonSectionReader below 8 has all the features that I would like to 7 have. The tool is capable of reading sections 6 of data from embedded json files. It also 5 provides a very comfortable mechanism to 4 deserialize.

https://www.nuget.org/packages/WonderTools.JsonSectionReader/

P.S. I am the maintainer of 3 this project, and this project was created 2 because I didn't find any other tool that 1 solves this problem to the extent I wanted.

More Related questions