Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Data-driven testing in NUnit?

In MSTest you can do something like:

[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", 
            "testdata.csv", "testdata#csv", DataAccessMethod.Sequential)]
public void TestSomething()
{
    double column1 = Convert.ToDouble(TestContext.DataRow["column1"]);
    ...
    Assert.AreEqual(...);
}

What is the equivalent code in NUnit 2.5?

like image 942
Nobody Avatar asked Oct 27 '10 19:10

Nobody


People also ask

Is NUnit is data driven framework?

Selenium is one of the most famous UI test automation tool which works well with the NUnit testing framework.

How can you make a NUnit TestCase data driven?

The first way to create data driven tests is by using the [TestCase] attribute that NUnit provides. You can add multiple [TestCase] attributes for a single test method, and specify the combinations of input and expected output parameters that the test method should take.

What type of testing tool is NUnit?

NUnit is an open-source unit testing framework for the . NET Framework and Mono. It serves the same purpose as JUnit does in the Java world, and is one of many programs in the xUnit family.

Is NUnit automated testing?

NUnit is not an automated GUI testing tool.


3 Answers

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

Use the csv reader from code project, wrapped up in a private method returning IEnumerable in your test class, and then reference this with a TestCaseSource attribute on your test cases. Include your csv file in your 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 post at: http://timwise.blogspot.com/2011/05/data-driven-test-in-nunit-with-csv.html

like image 146
Tim Abell Avatar answered Oct 16 '22 12:10

Tim Abell


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

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

like image 10
Dave White Avatar answered Oct 16 '22 13:10

Dave White


Here is another example very similar to Tim Abell's however not using a framework for the CSV reader and showing the specifics of the test. Note when you use the TestCaseAttribute 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 3rd column is a sum of the first two columns and this will be asserted in the unit test.

Results:

results

Find below an alternative using TestCaseData objects and setting a return type (which 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);
        }
    }
like image 4
Thulani Chivandikwa Avatar answered Oct 16 '22 13:10

Thulani Chivandikwa