How to run XUnit test using data from a CSV file

混江龙づ霸主 提交于 2019-12-01 21:28:00

You'll need to create a custom xUnit.Sdk.DataAttribute. This is an example which will read in data in this form.

MyCsv.csv

sep=,
csvRowOne,csvRowTwo,csvRowThree
15,"Just A Test","Apples are Red"

Then you would call it like this:

  [Theory]
  [CsvData(@"C:\MyCsv.csv")]
  public void TestWithCSVData(int csvRowOne, string csvRowTwo, string csvRowThree)

It just parses strings and ints, but you can extend the ConvertParameter method to do more.

CsvDataAttribute.cs

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class CsvDataAttribute : DataAttribute
{
    private readonly string _fileName;
    public CsvDataAttribute(string fileName)
    {
        _fileName = fileName;
    }

    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        var pars = testMethod.GetParameters();
        var parameterTypes = pars.Select(par => par.ParameterType).ToArray();
        using (var csvFile = new StreamReader(_fileName))
        {
            csvFile.ReadLine();// Delimiter Row: "sep=,". Comment out if not used
            csvFile.ReadLine(); // Headings Row. Comment out if not used
            string line;
            while ((line = csvFile.ReadLine()) != null)
            {
                var row = line.Split(',');
                yield return ConvertParameters((object[])row, parameterTypes);
            }
        }
    }

    private static object[] ConvertParameters(IReadOnlyList<object> values, IReadOnlyList<Type> parameterTypes)
    {
        var result = new object[parameterTypes.Count];
        for (var idx = 0; idx < parameterTypes.Count; idx++)
        {
            result[idx] = ConvertParameter(values[idx], parameterTypes[idx]);
        }

        return result;
    }

    private static object ConvertParameter(object parameter, Type parameterType)
    {
        return parameterType == typeof(int) ? Convert.ToInt32(parameter) : parameter;
    }
}
Chris Jansson

xUnit does not have this exact capability built in, it does however have extension points for type of use case. Much of xUnit can be replaced and customized, new test case data sources are one of the more common ones.

The Xunit.Sdk.DataAttribute is the extension point the ExcelDataAttribute uses.

A typical implementation would look something like this

public class CsvDataAttribute : DataAttribute
{
    readonly string fileName;

    public CsvDataAttribute(string fileName)
    {
        this.fileName = fileName;
    }

    public override IEnumerable<object[]> GetData(MethodInfo testMethod)
    {
        //Parse CSV and return an object[] for each test case
    }
}

The implementation of ExcelDataAttribute is found here. https://github.com/xunit/samples.xunit/blob/885edfc2e84ec4934cd137a985c3b06dda043ab5/ExcelDataExample/ExcelDataAttribute.cs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!