13

Using MSTest in a .Net Core Unit test project. I am attempting to use a csv datasource to provide the data for a test method.

Previously, I would use something like below in a .Net Framework test project:

[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", @"data.csv", "data#csv", DataAccessMethod.Sequential),
     DeploymentItem("data.csv"),
     TestMethod]
    public void ValuesController_Post()
    {
        _controller.Post(TestContext.DataRow["body"]);
        _valuesRepository.Verify(_ => _.Post(It.IsAny<string>()), Times.Once);
    }

The key here being the DataRow property found in TestContext. This doesn't appear to exist in the .Net Core version of the TestContext.

How would I go about doing this in .Net Core?

David Jones
  • 141
  • 1
  • 9

2 Answers2

6

Since moving to aspnet core, I've never been able to use the same [Datasource(...)] attribute to iterate through test data, my data-driven tests are always skipped.

Have you considered switching to another approach with [DataTestMethod] and [DynamicData] with a custom source that reads you file ?

Here's a good article on this :

https://www.meziantou.net/2018/02/05/mstest-v2-data-tests

Maybe another way would be to read the whole file at the begining of the test and then iterate through the dataset as One single unit test?

Hope this helps.

Carl Verret
  • 576
  • 8
  • 21
0

It took me an afternoon to fiddle with things, but I finally found a solution. Since you don't specify your test or CSV file, here is a quick example I could get working.

Long story short, I installed the CsvHelper NuGet package, because parsing CSV is dead easy right up to the point it is not. As Carl Verret pointed out, you need to use the [DynamicData(...)] attribute above your test method, and then parse the CSV using CsvHelper.

The CSV File (Example.csv)

A,B,IsLessThanZero
1,2,FALSE
3,-5,TRUE

Important: Make sure this CSV file is included in your test project and "Copy To Output Directory" is set to "Always" in the properties for the CSV file in Solution Explorer.

Data Transfer Object Used By CsvHelper

public class AdditionData
{
    public int A { get; set; }
    public int B { get; set; }
    public bool IsLessThanZero { get; set; }
}

The Test Class

[TestClass]
public class ExampleTests
{
    // HINT: Look in {Your Test Project Folder}\bin\{Configuration}\netcore3.1\FolderYourCsvFileIsIn for the CSV file.
    //       Change this path to work with your test project folder structure.
    private static readonly string DataFilePath = Path.GetDirectoryName(typeof(ExampleTests).Assembly.Location) + @"\FolderYourCsvFileIsIn\Example.csv";

    [TestMethod]
    [DynamicData(nameof(GetData), DynamicDataSourceType.Method)]
    public void AddingTwoNumbers(AdditionData data)
    {
        bool isLessThanZero = data.A + data.B < 0;

        Assert.AreEqual(data.IsLessThanZero, isLessThanZero);
    }

    private static IEnumerable<object[]> GetData()
    {
        using var stream = new StreamReader(DataFilePath);
        using var reader = new CsvReader(stream, new CsvConfiguration(CultureInfo.CurrentCulture));
        var rows = reader.GetRecords<AdditionData>();

        foreach (var row in rows)
        {
            yield return new object[] { row };
        }
    }
}

After building your solution, you will see a single test in Test Explorer. Running this single test runs all variants defined in your CSV file:

Screenshot of test explorer showing one test named AddingTwoNumbers

Greg Burghardt
  • 17,900
  • 9
  • 49
  • 92