Related Articles:

Inside Out: TDD using C#

Visual Studio and .NET Unit Test Framework

Unit Test Automation with Visual Studio

Introduction

Unit Tests play an important role in delivering high quality software solutions. An ideal unit test is a piece of code (automated test) written by a developer which exercises a small but specific area of code functionality to ensure that it works as expected.

Why Unit Test

According to the Test Triangle, in a software project the largest number of tests must be Unit Tests. Because multiple individual Unit Tests exercises small units of functionality which spans over entire various areas of functionality offered by the software solution.

                                       

Unit Test Check-List

While writing Unit Test(s) following points must be considered and followed by the Developers and SDETs.

Check

Description

  √

Self-Describing Names

Unit Test method names must be Self-Describing and Pascal case.  For example choose Add_New_Customer_With_Valid_AcccountNumber over AddCustomer_with_validAcc or addCustomer etc.Also focus on naming style, keep the naming style consistent across all the tests methods and test.

   [ ]

A3 (Arrange, Asset, Act)

Make sure that all the Test Methods are designed around Arrange, Act and Assert.If required Refactor your code to fall into these three sections.

   [ ]

Test Happy and Sad Path

The unit test should cover all possible scenarios and strive for high code coverage and ensuring good quality metrics. Unit Test methods must exercise all possible use case scenarios to test the input validations, interactions, errors messages, edge cases and exceptions etc.

   [ ]

Make use of Attributes

Use Test Framework provided Attributes like :

[TestCategory(“<describe if its Unit or Integration Test>”)]

[TestCategory(“<Which section of the application is being tested>”)]

[Priority(n), TestCategory(“<define if it’s Gated or not-Gated build Tests>”)]

[WorkItem(xxxx)]

[Owner(“<who wrote this test>”)]

   [ ]

Have least number of asserts per test (if applicable)

A good Unit test should only have limited # of assert statements. It should unit test the very functionality, as indicated in its descriptive name.A well-defined Unit Test should contain only one assert statement per test and must not try to exercise all the validation/boundary checks etc. by multiple Assert() in one Unit Test method. .

   [ ]

Keep assert messages descriptive

Use descriptive messages to improve readability of code and the build log.Assert.IsTrue(customer.IsExist,”The Customer is not found in the Database”);

   [ ]

Unit != Integration

There is a very fine line between Unit and Integration, if you happen to go beyond what your function is supposed to be doing then you are not writing a Unit Test. I.e. Unit Test doesn’t focus on interaction with external systems and software layers/dependencies.Test Doubles (for example Microsoft Fakes framework) comes into the picture to write unit tests which has dependencies on external libraries and systems etc.

   [ ]

Follow OOP Design and Adopt DI

Following Dependency Injection will allow to convert potential Integration Tests into small and quickly testable Unit Tests by taking advantages of Test Doubles (e.g. Microsoft Fakes, Moq, FakeItEasy frameworks etc.)

   [ ]

Should be thorough

Unit Tests are supposed to test all the possible areas of functionality that are subject to failure due to incorrect input/validation checks/boundary checks etc. for given function/method.

   [ ]

Must be Repeatable

Unit Tests must be repeatable for every build and must produce the same results. The development best practice suggests that if you are working on code that is impacting a Unit Test then you must fix the affected Unit Test as well and ensure that it passes.

   [ ]

Have to be Independent

Unit Tests must be independent of another test. In other words, no collateral damage. Hence, a Unit Test must focus only on a small aspect of big functionality. When this Unit Test fails, it should be easy to discover where the issue is in the code. I.e. can be tested in isolation

   [ ]

Keep it Professional

Even though at times Unit Tests may appear to be very simple and small, you must write Unit Tests with coding practices as good as you use for your main development coding. You may want to follow Refactoring, Code Analysis and Code Review practices and so on as for your Test Projects as well.

  [ ]

No Collateral Damage

Make Sure to Run all related Unit Tests after any dev code change big or small; to verify and ensure that no collateral damage occurs or has been introduced.

  [ ]

If you break it, You bought it

If you are working on a feature and to verify no collateral damage, as a best practice run all the Unit Tests. If you observe that some Unit Tests started failing because of your code changes then you own to Fix those broken Unit Tests to make sure that continue to pass.

  [ ]

Track and  maintain the tests

The test code changes should be tracked and maintained as on-going effort. Continue to follow thedesign principles and coding guidelines.

  [ ]

Code Review the Tests

Just like any other Dev code, Unit Tests also needs to be code reviewed by peer. Regardless of size of the test; follow the process.Code review might include reviewing the name of test method, scenarios covered, conditions checked, scope of assertions and code / design smells etc.

  [ ]

I presented a Google hangout for Bangalore DotNet (BDotNet) user group on June 4th Wednesday 9pm IST (8:30am PST) 

 

 

Microsoft Visual Studio and .NET has its own UnitTest framework which is separate from the NUnit or other Automation Testing Frameworks.

First of all, let’s understand What is a Framework? Framework is an Architectural term and it means “Collection of Components”.

Code Example of Test Automation using Microsoft Visual Studio 2010

Business Logic which we want to test using Automation
I have a business logic which does some maths calculation and is available via a MathLibrary.dll

The source code of this MathLibrary business logic component is as shown below:

using System;
namespace MathLibrary
{
 public class MathClass
 {
  public int Sum(int n1, int n2)
  {
     if(n1<=0 && n2<=0)
     {
         throw new ArgumentException(“No Zero or Negative are allowed”);
     }
     else
     {
         return n1 + n2;
     }
  }
}

As it’s a dll component so test coverage of this is very critical to make sure that business logic is intact and returning right results.

To do so, instead of relying on a Manual Test Process through a UI which will be very cumbersome and tedious to continuously test the sanity of business logic, we can choose to Automate this test process.

As you might have noticed, we have written the Sum function (in MathLibrary.dll) in a Test Driven, style I.e the parameters passed are also being validated for all the possible test scenarios:
1- If aregument is +ve and non-zero then return the sum of passed arguments. 
2– If argument passed is 0 “zero” then throw an exception
3- if argument passed is -ve then throw an exception

How to approach Test Automation in general

Irrespective of what Unit Test tool and development technology you use Test process depends on two things.

1- Expected – Before we really perform a test our Test case tells us what to expect by this test case to verify success in case of a Sum taking two ints, we expect it to return exact result of adding two numbers.

2- Actual – When you perform the test what your result is.

If Expected meets the Actual then your Test Case is Passed, otherwise your Test Case is Failed

Hence we have to achieve Test Coverage for all the Test Cases in the above mentioned test scenarios.

To do so, we will use Microsoft Visual Studio 2008 or 2010 and then open a New Test Project as shown in the image below:

Now Once you will have this project Loaded, it will have a file UnitTest1.cs in it, this is the file you will be automating all the Test Cases for the MathLibrary.dll (our business logic) we have created.

In order to Automate the Test Cases in Microsoft Visual Studio using Unit Testing Framework, you need to understand few more things:

1- Test Automation Framework – Microsoft has its Unit Testing Framework implemented in a namespace which is Microsoft.VisualStudio.TestTools.UnitTesting

2- [TestMethod] attribute This is the attribute which needs to be present on each method which will actually represent a TestCase.

3- Assert class – This class is part of Microsoft’s Unit Testing framework, and we can use this class to verify if our Actual and Expected are same or not etc.

As mentioned above for each and every Test Case we have to write Automation code.

Note: Before we start coding the Automated TestCases, don’t forget to add all the References,
WebReferences etc. which your Test infrastructure will use.

I have covered Four Test Cases for Sum Function in MathLibrary.dll

// Test Case#1: to verify if passed ints are returning Right Result
[TestMethod]
public void TestSumResultAreEqual()
{
   MathLibrary.MathClass objMath = new MathClass();

   Assert.AreEqual(24, objMath.Sum(12, 12));
}

// Test Case#2: to verify if passed ints are Not returning Right Result
[TestMethod]
public void TestSumResultAreNotEqual()
{
    MathLibrary.MathClass objMath = new MathClass();

    Assert.AreNotEqual(25, objMath.Sum(12, 12));
}

// Test Case#3: to verify if passed ints are actually Zero
[TestMethod]
public void TestSumThrowExceptionWhenZero()
{
     MathLibrary.MathClass objMath = new MathClass();

     try
     {
         objMath.Sum(0, 0);
     }
    
     catch (ArgumentException)
     {          
         // logging code will go here
     }
}

// Test Case#4: to verify if passed ints are actually Negative
[TestMethod]
public void TestSumThrowExceptionWhenNegative()
{
    MathLibrary.MathClass objMath = new MathClass();

    try
    {
       objMath.Sum(-123, -456);
    }

    catch (ArgumentException)
    {
       // logging code will go here
    }
}

Once you have coded all the Test Cases to Test the functionality, its time to build the code and a TestProjectName.dll will be produced.

There are two ways to Test your automation code now:

1- Using Visual Studio IDE

Build and then Run the project within Visual Studio, you will see all the TestMethods being executed and showing Test Results as shown in the image below:

      
2- Using Visual Studio’s command prompt
Open Visual Studio’s command prompt and navigate to the folder where the TestProjectName.dll is located

and then run this command:mstest /testcontainer:TestProjectName.dll

           
Summary: This article explained the aproach to Test Automagtion using Microsoft Visual Studio’s Unit Testing Framework. Some basic fundamentals about Framework, what is expected out of a test and how to automate a business logic in a .dll form. The same approach can be used to even automate a WebService component etc.