Data-driven unit testing

This type of testing is useful in carrying out the same test multiple times with different input data from a data source. The data source can have any number of test records or data rows, and the test can be run successively for each row.

Instead of passing each data row value to the test application and executing an entire test for each data row, we link the test method to the data source. So when the test is run, the test method is executed for each data row in the source.

This is similar to web testing or load testing, with a data source attached to the web method parameters. This could be used in case of testing multiple user scenarios with different user logins to check the access permission, or to validate the data based on the user roles.

Let's consider one simple example of a method which takes the two parameters of quantity and unit price. The result of the method will be to return the multiplied value of these two values and apply a percentage of tax to it:

        public double CalculateTotalPrice(double uPrice, int Qty)
        {
            double totalPrice;
            double tax = 0.125;
            totalPrice = uPrice * Qty + (uPrice * tax * Qty); // 
            return totalPrice;
        }

Create a unit test for the preceding example. The unit test code would contain the following code for the preceding method:

        [TestMethod()]
        public void CalculateTotalPriceTest()
        {
            Class1 target = new Class1(); 
            double uPrice = 0F; 
            int Qty = 0; 
            double expected = 0F; 
            double actual;
            actual = target.CalculateTotalPrice(uPrice, Qty);
            Assert.AreEqual(expected, actual);
        }

The data source needs to be created before linking and binding it with the test method and properties. The data source can be of different formats such as CSV, XML, Microsoft Access, Microsoft SQL Server Database or Oracle Database, or any other database. For this example, we will consider a CSV file which has five records each record with values for UnitPrice, Quanity, and ExpectedTotalPrice. The test method expects two parameter values to be passed and returns the calculated value to match and check with the expected value:

Data-driven unit testing

Add the CSV file to the Test Project to use as the data source for the test. The unit test framework creates a TestContext object to store the data source information for a data-driven test. The framework then sets this object as the value of the TestContext property that we created. We can include this TestContext property to the unit test class as follows:

  private TestContext testContextInstance;
  public TestContext TestContext
{
  get { return testContextInstance; }
  set { testContextInstance = value; }
}

Add the data source attribute and specify the connection string and the name of the table that you use in the test method. To use the CSV file as the data source, add the Microsoft.VisualStudio.TestTools.DataSource.CSV to the DataSource attribute and specify the connection string followed by the table name. In this case the CSV file name itself is the table name. The third parameter for the attribute is the data access method which can be of the sequential or random type. Select sequential to execute the test method with data rows in the order they are present in the source.

The testContextInstance.DataRow is used to fetch the value from the current row for the current instance of the test. For example, if we have five rows in the data source, there will be five different instances of tests for each row. The column value from the current row is fetched using the testContextInstance.DataRow and assigned to the required test. The following example uses the Assert.AreEqual method to check if the actual value is as per the expected value from the data source. Custom error messages can be used in the Assert method to display a specific message if the test fails:

       [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\Data.csv", "Data#csv", DataAccessMethod.Sequential), TestMethod()]
        public void CalculateTotalPriceTest()
        {
            Class1 target = new Class1(); 
            double uPrice = 0F; 
            int Qty = 0; 
            double expected = 0F; 
            double actual;
            expected = Convert.ToDouble(testContextInstance.DataRow["ExpectedTotalPrice"]);
            actual = target.CalculateTotalPrice(Convert.ToDouble(testContextInstance.DataRow["UnitPrice"]), 
                     Convert.ToInt32(testContextInstance.DataRow["Quantity"]));
            Assert.AreEqual(expected, actual, "The expected value is {0} but the actual value is {1}", expected, actual);
            Trace.WriteLine("Expected:" + expected + "; Actual:"+ actual);
        }

Now the test method is ready, with the data source and data fields bound within the test method.

Build the solution and open the Test Explorer window to see the test method listed. Select the test and run it. As per the data that is present in the data source which is the CSV file, four out of five tests pass. One test fails because the actual is not equal to the expected value. The summary of the Test Result displayed within the test explorer is illustrated in the following screenshot:

Data-driven unit testing

On running the test, the Test Explorer window shows the test execution progress for each row in the data source. Once the test is completed for all of the rows in the data source, we can see the overall Test Result based on the results of all individual tests. If even one test fails, the end result of the Test Run will be a failure. To get the Test Run to pass, all individual tests within the selected Test Run must pass.

The detailed output of each test is shown by clicking the output hyperlink below the test output. The following screenshot shows one of the test output which shows the actual and expected values from the test method, as shown in the following screenshot:

Data-driven unit testing

For failed tests, there are Source and StackTrace hyperlinks, which take you to the line of code in the method which throws the error or fails the test.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.137.58