简体   繁体   中英

File-driven unit tests in Visual Studio?

I am creating unit tests for a class library. There are hundreds of tests, but they're all testing the same single method. The only difference is the inputs and outputs. I'd like to move the definitions of these tests to some kind of text files so I can manage them more conveniently.

Can I create an adapter so that I can continue to use the VS test runner? I found some references to [DataSource] attributes, but I'd prefer to have the tests in separate text files, not some kind of queryable database.

If you are using MSTest V2, you can use attribute-based data inputs like @Floris' example did with xUnit. See https://blogs.msdn.microsoft.com/devops/2016/06/17/taking-the-mstest-framework-forward-with-mstest-v2/ for the announcement, and it should look something like this:

[DataTestMethod]
[DataRow("filename1")]
[DataRow("filename2")]
public void MyTestMethod(string inputfile)

The DataSource attribute can refer an XML file, too.

Example:

// SortTest elements are read from the XML named SortTestDataSource.xml
[TestMethod]
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.XML", "|DataDirectory|\\SortTestDataSource.xml", "SortTest", DataAccessMethod.Sequential)]
public void SortTest()
{
    var reflist = Enumerable.Range(0, 100);

    // And you can read the XML attributes of each row as follows 
    int count = Int32.Parse((string)TestContext.DataRow["Count"]);
    SortingAlgorithm algorithm = (SortingAlgorithm)Enum.Parse(typeof(SortingAlgorithm), (string)TestContext.DataRow["Algorithm"]);
    Order order = (Order)Enum.Parse(typeof(Order), (string)TestContext.DataRow["Order"]);
    int seed = Int32.Parse((string)TestContext.DataRow["Seed"]);

    var array = SortHelper.CreateArray<int>(count, order, seed);
    Sorter<int> sorter = new Sorter<int>();
    sorter.Sort(array, algorithm);
    Assert.IsTrue(reflist.SequenceEqual(array));
}

And the XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Elements>
  <SortTest Count="100" Algorithm="SelectionSort" Order="Random" Seed="0"/>
  <SortTest Count="100" Algorithm="QuickSortPivotFirst" Order="Random" Seed="0"/>
  <SortTest Count="100" Algorithm="QuickSortPivotMiddle" Order="Random" Seed="0"/>
  <SortTest Count="100" Algorithm="MergeSortTopDown" Order="Random" Seed="0"/>
  <SortTest Count="100" Algorithm="MergeSortBottomUp" Order="Random" Seed="0"/>
</Elements>

I know the question is about if you can create an adapter, but maybe there is another way without it. Assuming that the test itself is still in your test project, but only the data needs to come from a file, then you could use a Theory (xUnit) with the filenames that you want to test against.

[Theory]
[InlineData("filename1")]
[InlineData("filename2")]
[InlineData("filename3")]
public void MyFirstTheory(string filename)
{
// read the file and use it for testing
}

Other ways include creating a IEnumerable for the arguments which gives more flexibility (you could then remove the filename from the inline data and pass it a proper object). See http://hamidmosalla.com/2017/02/25/xunit-theory-working-with-inlinedata-memberdata-classdata/ for example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM