Thursday, 9 July 2009

Data driven tests with MSTest

You can use CSV or Excel documents as data sources to drive parameterised unit tests with MSTest. For the following class:

    3     public static class MyWidget

    4     {

    5         public static int MyBusinessLogic(int valueA, int valueB)

    6         {

    7             return valueA * valueB;

    8         }

    9     }

You can write the following unit tests:

    3     using System;

    4 

    5     using Microsoft.VisualStudio.TestTools.UnitTesting;

    6 

    7     [TestClass]

    8     public class MyWidgetTests

    9     {

   10         [TestMethod]

   11         [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "MyWidgetTests.csv", "MyWidgetTests#csv", DataAccessMethod.Sequential)]

   12         public void TestMyBusinessLogicWithCsv()

   13         {

   14             int valueA = Convert.ToInt32(TestContext.DataRow["valueA"]);

   15             int valueB = Convert.ToInt32(TestContext.DataRow["valueB"]);

   16             int expectedResult = Convert.ToInt32(TestContext.DataRow["expectedResult"]);

   17             int actualResult = MyWidget.MyBusinessLogic(valueA, valueB);

   18             Assert.AreEqual(expectedResult, actualResult, "The result returned from the widget was not as expected.");

   19         }

   20 

   21         [TestMethod]

   22         [DataSource("System.Data.Odbc", "Dsn=Excel Files;dbq=|DataDirectory|\\MyWidgetTests.xlsx", "MyWidgetTests$", DataAccessMethod.Sequential)]

   23         public void TestMyBusinessLogicWithExcel()

   24         {

   25             int valueA = Convert.ToInt32(TestContext.DataRow["valueA"]);

   26             int valueB = Convert.ToInt32(TestContext.DataRow["valueB"]);

   27             int expectedResult = Convert.ToInt32(TestContext.DataRow["expectedResult"]);

   28             int actualResult = MyWidget.MyBusinessLogic(valueA, valueB);

   29             Assert.AreEqual(expectedResult, actualResult, "The result returned from the widget was not as expected.");

   30         }

   31 

   32         public TestContext TestContext{ get; set; }

   33     }

Notice the two unit tests are identical save for the test name and the “DataSource” attribute. The code is pretty self explanatory, the two tests are driven by data from different sources. The only things to note are the presence of the “TestContext” and the contents of the Data Source.

For CSV sources (the first in the example):

  • “Microsoft.VisualStudio.TestTools.DataSource.CSV” specifies the data source type.
  • “MyWidgetTests.csv” is the connection string and needs to be name of the file to read the values from.
  • The “MyWidgetTests#csv” value is the “table name”. When using files, it needs to match the filename, with a hash (“#”) instead of the period (“.”).

An example file is as follows:

image

For Excel sources (the second example):

  • “System.Data.Odbc” specifies the data source type.
  • “Dsn=Excel Files;dbq=|DataDirectory|\\MyWidgetTests.xlsx” is again the connection string, replace your filename accordingly. The “DataDirectory” value is replaced by the MSTest framework and points to the directory the tests are run from.
  • The “MyWidgetTests$” value is the “table name”. When using Excel files, it needs to to be the name of the of the Worksheet containing the data (see below).

An example file is as follows:

image

Note the you can have multiple Worksheets in a single Excel file, this means you can drive different tests from the same Excel file.

You will need to have the CSV and Excel files set as deployment items in the Test Run Config:

image


1 comments:

Unknown said...

Thanks for your post!

You can also make the path to the data source configurable, see http://www.codeproject.com/Tips/629895/Data-Driven-Testing-by-Excel-Named-Region

About Me