NUnit中的数据驱动测试?

15
在MSTest中,你可以像这样做:

[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(...);
}

NUnit 2.5中的等效代码是什么?

4个回答

12

我已经成功实现了在NUnit中基于csv的数据驱动测试,方法如下:

使用来自代码项目的csv读取器,将其封装在您的测试类中返回IEnumerable的私有方法中,然后在测试用例上使用TestCaseSource属性引用它。将您的csv文件包含在项目中,并将"复制到输出目录"设置为"始终复制"。

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

原帖地址:http://timwise.blogspot.com/2011/05/data-driven-test-in-nunit-with-csv.html


10

我会查看 NUnit 2.5 中的 参数化测试文档 ,看看是否可以做类似于您正在那里进行的操作。我不记得 NUnit 有内置的 CSV 读取属性来驱动参数化测试。可能有社区插件在某个地方。

我还应指出,如果您只是寻找非 MS 单元测试框架库来帮助您,xUnit.net 确实具有此功能。请查看这篇来自 Ben Hall 的 博客文章


谢谢 - 我已经做了一些调查。没有这样的插件存在。也许我只能自己制作一个。我之所以要求 NUnit 是因为它是我使用过的唯一的测试框架,仅此而已。 - Nobody
2
如果使用xUnit可以使您的测试更轻松,请不妨尝试一下。它与NUnit非常相似(都是由James Newkirk开发的!),并且可以很容易地与NUnit共存,直到您确定是否要完全切换为止。我不建议将xUnit和NUnit同时作为您正在进行的解决方案的一部分,因为这两个运行器不同,并且我认为它们没有任何能力运行对方的测试。 - Dave White

4

这里有另一个与Tim Abell非常相似的示例,但不使用CSV读取器框架,并显示测试的具体内容。请注意,当您使用TestCaseAttribute时,可以省略TestAttribute。

        [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 数据:

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

注意:第三列是前两列的总和,这将在单元测试中进行断言。

结果:

results

以下是使用 TestCaseData 对象及设置返回类型的替代方法(这当然是必需的)。

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

0

MS Test提供了一种机制,可以从不同的数据源获取测试数据。然而,NUnit默认情况下不支持此功能。

我赞成将测试数据和代码分离,特别是对于较大的测试用例。当我将它们分开时,我的期望是: 1. 测试数据易读性 2. 测试数据易于修改 3. 单元测试应在本地和构建环境中轻松运行

JsonSectionReader下方列出的所有功能都是我想要的。 该工具能够从嵌入式JSON文件中读取数据部分。它还提供了一种非常舒适的反序列化机制。

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

顺便说一下,我是这个项目的维护者,创建这个项目的原因是因为我没有找到其他解决这个问题的工具能够满足我的要求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接