Thursday, August 6, 2009

NUnit Testing Tutorial

NUnit: A tutorial
What is unit testing?

According to Jeff Canna, unit testing ensures that a particular method of a class
successfully performs a set of specific tasks. Each test confirms that a method
produces the expected output when given a known input.

What is NUnit?

NUnit is an open source framework that facilitates unit testing for all .NET languages.

How do I get NUnit?

Download the appropriate file from here and install it. That’s it!!

Writing NUnit tests

One question that crossed my mind when I was learning NUnit was whether I should
create my test project as an executable or as a class library. I finally decided to use a
class library because I wouldn’t be running my test project in a stand-alone manner
anyway. But, creating a test project as an executable would cause no problems. It’s up
to you to decide.

Now, let’s get going. Let us first write the class for which we would write unit test
cases. Our class would be called Arithmetica. It would contain four methods to
perform the basic arithmetic operations – Add, Subtract, Multiply and Divide.
using System;

namespace Arithmetica
{
public class Arithmetica
{
public int Add(int augend, int addend)
{
return augend + addend;
}
public int Subtract(int minuend, int subtrahend)
{
return minuend - subtrahend;
}public int Multiply(int firstFactor, int secondFactor)
{
return firstFactor * secondFactor;
}
public int Divide(int dividend, int divisor)
{
return dividend / divisor;
}
}
}

The above code should be placed in a separate project and compiled into a separate
assembly. That’s how unit testing is performed. The test cases are not a part of the
production code. Implementing unit test within the main assembly not only bloats the
actual code, it will also create additional dependencies to NUnit.Framework.
Secondly, in a multi-team environment, a separate unit test assembly provides the
ease of addition and management. [3]
Now, let’s write the test cases for the Arithmetica class. This would involve the
following steps:
1. Create a new project of “Class Library” type (see discussion above) and name it
Arithmetica.UnitTests.
2. Add the project containing the Arithmetica class into the solution of
Arithmetica.UnitTests.
3. Add reference to nunit.framework.dll. This DLL is located in a directory called bin
under the directory where NUnit is installed.
4. Add the following lines in the class in which you are writing the unit test cases:
using System;
using NUnit.Framework;
5. The class which contains the tests must be declared public and decorated with the
TestFixture attribute as follows:
namespace Arithmetica
{
[TestFixture]
public class ArithmeticaUnitTests
{
}
}
6. Now, you may want to do setup activities which are performed before executing
any test. In our case, we want to create an object of the Arithmetica class. This is done
by decorating the method in which you want to perform the setup activities with the
TestFixtureSetup attribute as follows:
[TestFixture]
public class ArithmeticaUnitTests{
private Arithmetica arithmetica;
[TestFixtureSetUp]
public void SetUp()
{
arithmetica = new Arithmetica();
}
}
Note that a TestFixture can have at most one TestFixtureSetup method.
7. You may also want to perform a set of clean up activities after executing all the
tests. The method which does this is decorated with the TestFixtureTearDown
attribute.
namespace Arithmetica
{
[TestFixture]
public class ArithmeticaUnitTests
{
private Arithmetica arithmetica;
[TestFixtureSetUp]
public void SetUp()
{
arithmetica = new Arithmetica();
}
[TestFixtureTearDown]
public void TearDown()
{
arithmetica = null;
}
}
}
Again, a TestFixture can contain at most one TestFixtureTearDown method. Other
setup and teardown attributes for NUnit include SetUp, TearDown, SetUpFixture and
TearDownFixture. You may refer NUnit documentation for these.
8. Now, let’s write the test for the Add method. Every test method must be decorated
with the Test attribute. You can have as many test methods in a test fixture as you
desire.
[Test]
public void TestAdd()
{
int result = arithmetica.Add(2, 3);
Assert.AreEqual(result, 5);
}
Here, the Add method of Arithmetica class is called with the parameters 2 and 3 and
the sum is stored in result. Then, we check whether result is equal to 5. You can read
more about assertions in NUnit documentation.9. If you are expecting an exception to be thrown in the test method, you can decorate
it with the ExpectedException attribute as follows:
[Test, ExpectedException(typeof(DivideByZeroException))]
public void TestDivide()
{
int result = arithmetica.Divide(2, 0);
}
It must be noted here that the precise type of the exception must be specified in the
ExpectedException attribute. Using Exception instead of DivideByZeroException will
cause the test to fail.
10. Similarly, you may write the other test cases. Here is the listing of the tests that I
wrote:
using System;
using NUnit.Framework;
namespace Arithmetica
{
[TestFixture]
public class ArithmeticaUnitTests
{
private Arithmetica arithmetica;
[TestFixtureSetUp]
public void SetUp()
{
arithmetica = new Arithmetica();
}
[TestFixtureTearDown]
public void TearDown()
{
arithmetica = null;
}
[Test]
public void TestAdd()
{
int result = arithmetica.Add(2, 3);
Assert.AreEqual(result, 5);
}
[Test]
public void TestSubtract()
{
int result = arithmetica.Subtract(3, 2);
Assert.AreEqual(result, 1);
result = arithmetica.Subtract(2, 3);
Assert.AreEqual(result, -1);
}
[Test]
public void TestMultiply(){
int result = arithmetica.Multiply(2, 3);
Assert.AreEqual(result, 6);
}
[Test, ExpectedException(typeof(DivideByZeroException))]
public void TestDivide()
{
int result = arithmetica.Divide(4, 2);
Assert.AreEqual(result, 2);
result = arithmetica.Divide(2, 0);
}
}
}
After this, build the assembly. Please note that the TestFixtureSetUp,
TestFixtureTearDown and Test methods must be defined with the following method
signature:
public void MethodName()


Puneet Singla

1 comment:

Unknown said...

Hi Puneet,

I'm beginner in Nunit, could you please share some sample test projects/code with me.

Will be of great help.

Thanks,
Sarita