开发者

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 equivalen开发者_开发问答t code in NUnit 2.5?


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


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


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:

Data-driven testing in NUnit?

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


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

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

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

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

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜