Description
This article should help C# user to get the most out of NUnit. Therefore, we are going to cover not only the usage of NUnit, but also the small tricks on how to set it up most efficiently.
In order for me to keep these articles always up-to-date (in the case that a new NUnit comes out), I made a small page over here. Be sure to check that page for new articles, since I have a bit more control over that site and can therefore add articles faster.
I will split this topic into two parts. The first part will mainly describe the very basics of setting up NUnit. It is really meant to be usable by everyone, so if somebody has a problem, please email me under here. The second part will be a more advanced treatment of how NUnit can be effectively used in your production pipeline. Here I also want to point out some non documented short cuts to using NUnit.
This article is based on Visual Studio .Net Beta 2 and NUnit 1.10. Any later versions might differ. The information here can also be used for other .NET languages, but the article is mainly focusing on C#. I also want to point out another good article, which goes over the basics of NUnit, it can be found here.
In order to get everybody on the same level, I will very quickly outline what a Unit Test and a Unit Test Harness is.
Unit Tests
To summarize, a Unit Test is a small piece of code (should be below 5-10 lines) which tests a small part (most times a single function) of a program/class/module. The idea behind Unit Tests is that if you have several hundreds of Unit Tests running in your application, you will solve a lot of bugs before they started to cost a lot. In addition I found out that making Unit Tests while you write code (called Test-First Programming) creates cleaner and better designed code. But that is another story.
So when we write a class with five public member functions, then we also want to write at least five Unit Tests to ensure that our cat has not walked over our keyboard while we were getting coffee.
Unit Test Harness
Now the concept of self-testing software sounds quite tempting (at least to me), however a big challenge remains, and that is to structure the tests so that you can have hundreds of automatic tests in one program which can execute within 1 sec. That is why Kent Beck decided to write a whole system which helps you to cope with this challenge. Kent created XUnit which was originally for SmallTalk, but other languages quickly copied it. NUnit brings now XUnit to all .Net languages. It can be found here and is maintained by Philip Craig. So to summarize it a Test Harness is a system which helps you write, store, setup, and run tests.
NUnit
OK, now that we covered the basics (and you hopefully did not fall asleep yet) we can tackle the actual setting up of NUnit.
NUnit - Part I
1. Download + Install NUnit
Whenever you want to use a component, it is always good to have it. Therefore, go to this page and download the newest build of NUnit. (You can download the .msi file, and the install program will do the rest.)
2. Add a reference to your project
Now the next step is to add a reference of NUnit to your project. You can do this by right-clicking on the reference icon under your project in the solution explorer (as seen in Picture1) and choosing "Add Reference".
OK now choose COM and browse (as seen in Picture2) to your NUnit directory (mine is C:Programs\NUnit). Go under the "bin" directory and choose NUnitCore.dll.
At this point, we have added the NUnit Library to our project. Now we can slowly begin to use it.
3. Add the "using" Statement
In order to be able to use it, we must add it in our source as follows:
// ...
using NUnit.Framework;
// ...
OK now we are setup to write some more serious code. In order to make some sense of this following, code let us assume that our company is trying to bring out a clone of the normal "calc.exe" calculator. Now, this calculator will have several classes. We got lucky and were awarded the task of writing the addition and subtraction methods for the calculator. These methods are in a class called CalcInt which takes care of processing integers.
Our classes which is quite simplified, looks like following:
public
class CalcInt //Class which processes all Integer operations for our Calculator program
{
public int add(int a,int b) //method to add two integers
{
return a+b;
}
public int sub(int a,int b) //method to subtract two integers
{
return a-b;
}
}
OK, we might not get the Field's Medal for this, but it will suffice for explanatory reasons. Now we can continue our steps.
4. Create an empty TestCase
Ok, here is where we enter the realm of NUnit. In order to test something we need a so called TestCase. Most times you will make one TestCase per class.
So our TestCase class looks like following: (Don't worry about those other functions just use them in every TestCase. You must make some simple modifications which your compiler will remind you of. So the Constructor obviously needs to be the same name as the class. And in the typeof(x), x needs also to be the name of the class.)
public
class TestingCalcInt : TestCase //TestCase class which holds all tests for the CalcInt Object
{
//Needed NUNIT Section
public TestingCalcInt (String name) : base(name) {} //Needed Constructor for NUnit
public static ITest Suite //Function over which lets you run this TestCase. It is only here because of //Polymorphism
{
get { return new TestSuite(typeof (TestingCalcInt));}
}
//Actual Test Setup Section
private CalcInt mycalc; //This will house the CalcInt which we will test
protected override void SetUp() //Function which gets called before every test
{
mycalc=new CalcInt(); //no before every test we will get a clean new CalcInt in mycalc
}
}
In order to make it as quick as possible, I most times copy and paste these three functions when I make a new TestCase.
5. Filling the TestCase
We have a TestCase now, which does not test anything yet. Not the most useful thing. In order to add tests we add functions which start with the prefix "test". They are then automatically found by NUnit and included in the later tests.
//this should be added inside of the TestingCalcInt class
public void testadd()//any function which starts with "test" will be added as tests. Make sure that the signature is //always the same. So make these functions public and void
{
//remember mycalc is already setup for us over the SetUp function
AssertEquals(20,mycalc.add(10,10)); //AssertEquals comes from NUnit and ensures that the first statement is equal //to the second argument. If this is not the case it will display an error in the tests later.
}
public void testsub()
{
AssertEquals(7,mycalc.sub(10,3));
}
In testadd(), we have a whole test in only one line. We are checking the add function of CalcInt and make sure that 10+10=20. The same is happening in testsub, but instead, we check subtraction, and without all the comments. Also, always make sure to write always the expected value as the first argument and the actual value as second argument in AssertEquals . I don't know if this is a NUnit bug or if it was already like this in XUnit. It certainly is unintuitive.
6. Build your project
Just click run in Debug mode so that your project gets built. The interesting thing about how NUnit works is that you can simply use your exe file for the testing, so you do not need to change your build process. Although in the next part of this article, we will see that this is the only way we can use NUnit to it's fullest fullest potential.
7. Start NUnitGUI
Go to the NUnit/bin directory (were you have referenced your project to before) and start the NUnitGUI.exe application with your normal explorer.
A window should open looking similar to this:
Now click on browse, change the file selection at the bottom to "all", and go to your project directory. Here go into your bin directory and choose the exe/dll file which you have been working on. So if our Project was called CalcInt, we would choose CalcInt.exe.
8. Run the tests
Now you should see all the TestCases in the "Type Name" field. Choose the one you want to test and click Run. You should get something like this:
9. Keep Testing & Fix your code
Depending on the time of day and how much Mountain Dew you've had, you will actually see, quite often something more similar to this:
Here you see that there was one Failure (which is a test failling, opposed to an error which is an expection being thrown).
But do not worry. You're still connected to NUnit correctly, so my job is done :). However, now yours start since you need to fix a failed test.
Conclusion
We have seen how NUnit can be used in a normal project. You have learned how to make TestCases and you know how to use the NUnitGUI. The only problem is that our whole process is still quite slow, especially if we have over 20 TestCases, since we need to choose each one and run it. In addition, the starting of NUnitGUI is quite a pain every time when we want to test something. But these topics will be covered in the next part of this article, which will be about the efficient use of NUnit.
Be sure to check out this page, which has an always up-dated version of this article due to the fact that I have full access to the site.