Chapter 4. Unit Testing

Unit testing is a type of testing or the technique to take the smallest piece of testable code isolated from the remaining software in the application and then determine whether it behaves as expected. Enterprise software applications usually comprises of multiple methods and functions with multiple lines of code integrated together. Identifying the piece of code that produces the defect is always a time-consuming task and the cost involved is also high. It is always a good practice to test the code in units and confirm the expectations before integrating the code module(s). Requiring all code to pass the unit tests before they can be integrated ensures standards and quality. It is the responsibility of the developer who has written the code to make sure that each unit of code behaves exactly as expected. The code should also be written in such a way that it can be tested independently. Another advantage is that every time a defect is fixed or code is modified, you need not retest the entire module or application. As long as the unit of code is tested and it produces the expected result, it should be fine. Automating the tests would help in re-running the tests whenever there is code change in any unit of code.

Visual Studio has the capability and feature to create, customize, and automate the unit tests, irrespective of type of the method whether it is public or private. Unit tests are just another class file, similar to any other class and method but having additional attributes to define the type as test class and the test method. The unit tests are created either manually by writing the code for class and methods, or by generating the skeleton code using the Create Unit Tests option from the Context menu and then customizing it.

The generated unit test code file contains special attributes assigned to the class and methods in it. Test classes are marked by the TestClass() attribute and each test method is marked with the TestMethod() attribute. Apart from these two, there are many other attributes used for unit testing. After generating the unit test class and methods, the Assert methods are used to verify the produced result with the expected value.

All unit test classes and methods are defined in the Microsoft.VisualStudio.TestTools.UnitTesting namespace. Any unit test created using Visual Studio should include this namespace. One of the main classes is the TestContext, which provides all the information for unit tests. This chapter covers the following topics in detail:

  • Creating unit tests
  • Naming and general settings
  • Assert statements and type of asserts
  • String asserts and collection asserts
  • Unit tests and generics
  • Data-driven unit tests
  • Code coverage for unit tests

Creating unit tests

There are two different ways of creating unit tests. One is the manually of writing the entire code for the test, and the other is to generate the unit test code for the class using Visual Studio and customizing it. To see how a test class is generated, consider the following class library which is a very simple example of a total price calculation.

For creating a new class library in Visual Studio, click on New | Project under the File menu option and select Class Library from the available Visual C# templates.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestLibrary
{
    public class Class1
    {
        public double CalculateTotalPrice(double quantity)
        {
            double totalPrice;
            double unitPrice;

            // Todo get unit price. For test let us hardcode it 
            unitPrice = 16.0;

            totalPrice = unitPrice * quantity;
            return totalPrice;
        }

        public void GetTotalPrice()
        {
            int qty = 5;
            double totalPrice = CalculateTotalPrice(qty);
            Console.WriteLine("Total Price: " + totalPrice);
        }
    }
}

Now the class file for total price calculation is coded, but needs to be unit tested. Using the File | New | Project menu option, select the unit testing type from the list and create a new project. In earlier versions of Visual Studio there used to be an easy way of creating a unit Test Project with the option of right-clicking on the method for which the Unit test has to be created. But that option is deprecated and no longer available in this version of Visual Studio for various reasons.

The default class contains a default class in the name of UnitTest1 and a test method in the name of TestMethod1.

The following code shows a few test methods created for the methods in the class library project. If the test method is incomplete and does not return a value yet, keep it inconclusive until it is complete and ready to return a value for evaluation.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
{
    [TestClass()]
    public class Class1Test
    {
        [TestMethod()]
        public void CalculateTotalPriceTest()
        {
            Class1 cls = new Class1(); 
            double quantity = 0F;
            double expected = 0F; 
            double actual;
            actual = cls.CalculateTotalPrice(quantity);
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("Verify the correctness of this test
			                     method");
        }

        [TestMethod()]
        public void GetTotalPriceTest()
        {
            Class1 cls = new Class1(); 
            cls.GetTotalPrice();
            Assert.Inconclusive("Method that does not return a value");
        }
    }
}

There are many attributes and properties available to the class and methods. A test method:

  • Must be decorated with the TestMethod() attribute
  • Should return void
  • Cannot have parameters

The following is the list of attributes used for test class and test methods:

Attributes

Description

TestClass()

To identify the unit test class within the file.

ClassInitialize()

The method with this attribute is used for preparing the class for the test. For example, setting up the environment or collecting details which are required for testing are handled within this method. The method with this attribute is executed just before the first test in the class; each test class can have only one method as the class initializer.

ClassCleanup()

The method with this attribute is used for cleaning or destroying the objects used in the test. This method is executed after all the tests in the class are run and each test class can contain only one method as the ClassCleanup method.

TestInitialize()

The method with this attribute is used for initializing or running the code before each test.

TestCleanup()

This method is run after each test in the class. This is similar to the ClassCleanup method but the difference here is that the method is executed once after each test.

TestMethod()

This attribute identifies the method to be included as part of the test. This method has the unit test code for the method in the original class file.

It is recommended to use the TestCleanup and ClassCleanup methods instead of the Finalizer method for all the test classes. The exceptions thrown from the Finalizer method will not be caught, which will result in unexpected results. The cleanup activity should be used for bringing the environment back to its original state. For example, during testing we might have updated or inserted more records to the database tables, or created a lot of files and logs. This information should be removed once the testing is complete and the exceptions thrown during this process should be caught and rectified. There are only a few initializing and cleanup methods that can be used within the test class.

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

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