DotNet UnitTestCustomDataSource

Overview

Using Data Driven Unit Tests from time to time, to tests multiple sets of data from a CSV file on the same Unit Test without duplicating the code, I came to a case where I wanted to loop through a list of files to run the same unit test. I could have done it with a csv file, but the annoying part was that each time I would add a file, I would have to add it to the csv file. Thus I started looking for another way, and I found out the ‘DynamicData’ attribute to define a custom source of data. Here is how I used it.

Context

Validating XML Schemas and Biztalk mappings using Unit Tests, I wanted to test multiple payloads in my mappings.

References

The Unit Test Project must reference the following classes :

  • Microsoft.Biztalk.TestTools.dll (C:\Program Files (x86)\Microsoft BizTalk Server\Developer Tools)
  • Microsoft.BizTalk.TOM.resources.dll (C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\PublicAssemblies\fr)
  • Microsoft.XLANGs.BaseTypes.dll (C:\Program Files (x86)\Microsoft BizTalk Server)
  • Biztalk Project(s) containing the Schemas and Mappings, must mark the project(s) to support unit tests in debug.

Include the following namespaces :

1
2
3
4
5
using System.IO; // for the File accesses
using (Biztalk Project namespaces);
using Microsoft.BizTalk.TestTools.Schema; // To support the testing functionalities included with Biztalk
using System.Collections.Generic; // To support the collection of object used for the DynamicData.
using System.Linq; // To support the collection of object used for the DynamicData.

DynamicData Attribute

First we need to amend the test class to accept parameters. In my case I want to receive a filename to validate.

1
2
3
4
        [TestMethod]
        public void BreUserRecord_InstanceValidationTest(string filename)
        {
            ...

Next we add a static method to retrieve the list of files to process. Note: In my case I could use ‘string’ instead of ‘object’, but for more complex data sets, object is recommended.

1
2
3
4
5
6
7
    public static IEnumerable<object[]> GetBreUserRecordFiles
    {
        get
        {
            return Directory.GetFiles("./Samples/", "BreUserRecord_*_Sample.xml").Select(s => new object[] { s });
        }
    }

Amend the Unit Test to do it s work. Add the ‘DynamicData’ Attribute, and set the test to perform.

1
2
3
4
5
6
7
[TestMethod]
[DynamicData(nameof(GetBreUserRecordFiles))]
public void BreUserRecord_InstanceValidationTest(string filename)
{
    BreUserRecord target = new BreUserRecord();
    Assert.IsTrue( target.ValidateInstance(filename, OutputInstanceType.XML));
}

Results

The Test Explorer view will show the results for all the cases. Visual Studio TextExplorer

Conclusion

The advantage of the methods for me are :

  • Single test to process multiple cases
  • Dynamically updates the tests with the files added to the Test Repository folder. Less Maintenance.
  • If one file fails, only the file failing will show as failed but all cases will be tested and show as succesfull. To Improve: Use a custom attribute that would accept a path and file pattern and isolate the code retrieving the list of files.

References