Saturday, 29 September 2012

NUnit Walkthrough


 

 

Unit Testing

What is Unit Testing?

Unit testing is a kind of testing done by a developer who develops the application. It is used to test the methods, properties, classes and assemblies. Unit testing is not the testing done by the quality assurance department. To know where unit testing fits into development, look at the image:

 
Unit Testing in Application Development

Unit testing is a software development process in which the smallest testable parts of an application, called units. Unit testing can be time-consuming and tedious. It demands patience and thoroughness on the part of the development team. Rigorous documentation must be maintained. Unit testing is commonly automated, but may still be performed manually.

The primary goal of unit testing is to take the smallest piece of testable part in the application, isolate it from the remainder of the code, and determine whether it behaves exactly as you expect. Each unit is tested separately before integrating them into modules to test the interfaces between modules. Unit testing has proven its value in that a large percentage of defects are identified during its use.

Unit tests are effective weapons in the fight against bugs. When you uncover a problem in your code, write a test that exposes this problem before fixing the code. This way, if the problem reappears, it will be caught with the test.


Finding the error (or errors) in the integrated module is much more complicated than first isolating the units, testing each, then integrating them and testing the whole.


There are several automated tools available to assist with unit testing. We will provide a few examples below:

1)      Using Nunit open source testing tool.

2)      Using Testdriven.Net tool.

3)      Using JetBrains Resharper.

4)      Using Visual Studio wizard.

 In the next phase we shall discuss about NUnit, which is a testing framework for .Net.

What is NUnit?

NUnit is the unit testing framework for performing unit testing based on the .NET platform. It is a widely used tool for unit testing and is preferred by many developers today. NUnit is free to use. NUnit does not create any test scripts by itself. You have to write test scripts by yourself, but NUnit allows you to use its tools and classes to make the unit testing easier. The points to be remembered about NUnit are listed below:

1.       NUnit is not an automated GUI testing tool.

2.       It is not a scripting language, all test are written in .NET supported language, e.g., C#, VC, VB.NET, J#, etc.

Example of sample NUnit Testing:

1.       Create a new console application.

2.       Add to it a public class called Calculation.

   public class Calculator

    {

        public int Add(int a, int b)

        {

            int x = a + b;

            return x;

        }

        public int Subtract(int a, int b)

        {

            int x = a - b;

            return x;

        }

        public int Multiply(int a, int b)

        {

            int z = a * b;

            return z;

        }

    }

 

3.       Write following code in Main.

static void Main(string[] args)

{

    Console.WriteLine("Enter two numbers\n");

    int number1;

    int number2;

    number1 = int.Parse(Console.ReadLine());

    number2 = int.Parse(Console.ReadLine());

 

    Calculator helper = new Calculator();

    int x = helper.Add(number1, number2);

    Console.WriteLine("The sum of " + number1 + " and " + number2 + " is " + x);

    int y = helper.Subtract(number1, number2);

    Console.WriteLine("The difference between " + number1 + " and " + number2 + "  is " + y);

    int z = helper.Multiply(number1, number2);

    Console.Write("Multiplication of two numbers is " + z);

}

 

4.       In the code above we are calling methods in calculation class.

5.       Now that we are ready with our project, let’s now add test project to the solution.

6.       Right click on Solution à Add New Project à ClassLibrary. Name =.Test (Standard for naming a NUnit Project).

7.       Download and install NUnit app from following location.


8.       Add reference to nunit.framework.dll, nunit.mocks.dll, pnunit.framework.dll (these files are in the folder - C:\Program Files (x86)\NUnit 2.6.1\bin\framework)

9.       Add TestConsole Project reference to Test project (right click on .Test Project à Add Reference à  Projects Tab à Select TestConsole à OK.

10.   Now add new class to Test project name=TestClass.

11.   Add namespace NUnit.Framework

12.   Add TestFixture attribute for a class.

13.   Add Test attribute for a method.

14.   Now, let’s create test methods for all three methods in the application.

15.   Add description for test attribute, it is purely optional.

16.   This is how test class looks like.

[TestFixture]

class TestClass

{

    [Test(Description="Test for Addition method")]

    public void AddTest()

    {

        Calculator helper = new Calculator();

        int result = helper.Add(20, 10);

        Assert.AreEqual(30, result);

    }

 

    [Test(Description="Test for subraction method")]

    public void SubtractTest()

    {

        Calculator helper = new Calculator();

        int result = helper.Subtract(20, 10);

        Assert.AreEqual(10, result);

    }

 

    [Test(Description="Test for multiplication method")]

    public void MultiplyTest()

    {

        Calculator helper = new Calculator();

        int result = helper.Multiply(10, 10);

        Assert.AreEqual(100, result);

    }

}

 

17.   In the above code, result is declared which is provided to test our method.

18.   Are equal method checks whether expected value and result are same.

19.   Now build project. Press ctrl+shift+B.

20.   Run NUnit Tool

21.   Click on file->OpenProject

22.   Add .Test.dll to test runner.

23.   File is loaded to GUI.

24.   Now you can see that there is an error in following method.

25.   That’s it when you find an error in particular method, you job is done.

26.   When your application is error free, you will see status only green.

 

Attributes

TestFixtureAttribute
This is the attribute that marks a class that contains tests and, optionally, setup or teardown methods.

There are a few restrictions on a class that is used as a test fixture.

  • It must be a publicly exported type or NUnit will not see it.
  • It must have a default constructor or NUnit will not be able to construct it.
  • The constructor should not have any side effects, since NUnit may construct the class multiple times in the course of a session.

TestAttribute
The Test attribute marks a specific method inside a class that has already been marked as a TestFixture, as a test method. For backwards compatibility with previous versions of Nunit a test method will also be found if the first 4 letters are "test" regardless of case.

The signature for a test method is defined as:    public void MethodName()

Note that there must be no parameters. If the programmer marks a test method that does not have the correct signature it will not be run and it will appear in the Test Not Run area in the UI that ran the program.

SetUpAttribute

This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called. A TestFixture can have only one SetUp method. If more than one is defined the TestFixture will compile successfully, but its tests will not run.

TearDownAttribute

This attribute is used inside a TestFixture to provide a common set of functions that are performed after each test method is run. A TestFixture can have only one TearDown method. If more than one is defined the TestFixture will compile successfully, but its tests will not run.

TestFixtureSetUpAttribute

This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture. A TestFixture can have only one TestFixtureSetUp method. If more than one is defined the TestFixture will compile successfully but its tests will not run.

TestFixtureTearDownAttribute

This attribute is used inside a TestFixture to provide a single set of functions that are performed once after all tests are completed. A TestFixture can have only one TestFixtureTearDown method. If more than one is defined the TestFixture will compile successfully but its tests will not run.

ExpectedExceptionAttribute
This is the way to specify that the execution of a test will throw an exception. This attribute has two constructors. The first (NUnit 2.0) takes a Type representing the exact type of the expected exception. The second (NUnit 2.2.4) takes the full name of the expected exception type as a string.

In either case, the runner will execute the test, which passes only if it throws the specified exception. If it throws a different exception then the test will fail. This is true even if the thrown exception inherits from the expected exception.

PlatformAttribute

The Platform attribute is used to specify platforms for which a test or fixture should be run. Platforms are specified using case-insensitive string values and may be either included or excluded from the run by use of the Include or Exclude properties respectively. Platforms to be included may alternatively be specified as an argument to the PlatformAttribute constructor. In either case, multiple comma-separated values may be specified.

CategoryAttribute

The Category attribute provides an alternative to suites for dealing with groups of tests. Either individual test cases or fixtures may be identified as belonging to a particular category. Both the GUI and console test runners allow specifying a list of categories to be included in or excluded from the run. When categories are used, only the tests in the selected categories will be run. Those tests in categories that are not selected are not reported at all.

This feature is accessible by use of the /include and /exclude arguments to the console runner and through a separate "Categories" tab in the GUI.

ExplicitAttribute

The Explicit attribute causes a test or test fixture to be ignored unless it is explicitly selected for running. The test or fixture will be run if it is selected in the GUI, if its name is specified on the console runner command line as the fixture to run or if it is included by use of a Category filter.

If a test or fixture with the Explicit attribute is encountered in the course of running tests, the runner treats it as if it had been ignored. The progress bar turns yellow and the test is listed in the report of tests not run

SuiteAttribute

The Suite Attribute is used to define subsets of suites based on user preference. The belief by the developers of this version is that the need for this will diminish because of the dynamic creation mechanism provided by the framework. However it is provided for backwards compatibility.

Note: There is no way to run user-defined suites in the forms interface.

IgnoreAttribute

The ignore attribute is an attribute to not run a test or test fixture for a period of time. The person marks either a Test or a TestFixture with the Ignore Attribute. The running program sees the attribute and does not run the test or tests. The progress bar will turn yellow if a test is not run and the test will be mentioned in the reports that it was not run.

This feature should be used to temporarily not run a test or fixture. This is a better mechanism than commenting out the test or renaming methods, since the tests will be compiled with the rest of the code and there is an indication at run time that a test is not being run. This ensures that tests will not be forgotten.

Sunday, 9 September 2012

Generics and How to write Generic class.


A Generic Class is not specific to any particular DataType. But the instance of such a class would be specific to a given DataType mentioned at the time of creating the instance/object that class.

Generic classes and methods combine reusability, type safety and efficiency in a way that their non-generic counterparts cannot. Generic collection classes are like Templates in C++.

Advantages of Generics

·         Type Safety -- Generic types enforce type compliance at compile-time, and not run-time (as in the case of using Object). This reduces the chances of data-type conflict during run-time.

·         Performance -- The data types to be used in a Generic class are determined at compile-time, hence there is no need to perform type casting during run-time, which is a computationally costly process.

·         Code reuse -- Since you only need to write the class once and customize it to use with the various data types, there is a substantial amount of code-reuse.


Easiest approach to write Custom Generic class: Let’s do this with an example:

Step1: First write a class for a specific data type.

For example below you will find an Stack Class with int datatype – Stack of int.

public class Stack
{
    int[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new int[size];
    }
    public void Push(int value)
    {
        top++;
        data[top] = value;
    }
    public int Pop()
    {
        int value = data[top];
        top--;
        return value;
    }
    public int GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i]);
    }
}

Limitation: In type of class can be used only for one datatype and for every data type we want to


Step2: Replace the specific datatype (eg: int) with Object and ensure that it still doesn’t have any errors:
 
public class Stack
{
    object[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new object[size];
    }
    public void Push(object value)
    {
        top++;
        data[top] = value;
    }
    public object Pop()
    {
        object value = data[top];
        top--;
        return value;
    }
    public object GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i]);
    }
}
 
Limitation: Because Object datatype is used in same instance we can have "int" and "string"...this makes the above class as NOT TYPESAFE....

 
Step3: Replace object with T (Generic Type) as in example below:
 
public class Stack<T>
{
    T[] data;
    int top = -1;
    public Stack(int size)
    {
        data = new T[size];
    }
    public void Push(T value)
    {
        top++;
       data[top] = value;
    }
    public T Pop()
    {
        T value = data[top];
        top--;
        return value;
    }
    public T GetTopElement()
    {
        return data[top];
    }
    public void Print()
    {
        for (int i = 0; i <= top; i++)
            Console.WriteLine(data[i].ToString());
    }
}

This class can be used as in program below:
class Program
{
    static void Main(string[] args)
    {
        Stack<int> s = new Stack<int>(5);
        s.Push (2);
        s.Push (5);
        s.Push (22);
        s.Push(“Demo”); //Compilation Error.
        s.Print();
       Stack<string> ss = new
                                          Stack<string>(10);
        ss.Push ("Demo");
        ss.Push("Test");
    }
}

Conclusion:
This same stack class can be used for instantiating for “int” and “string”….
Same generic class can be reused for different datatypes for different objects and a particular instance would allow only one type of item. That is why we say that generic classes give us the advantage of reusability and type safety.