« Dealing with Frustrating Development Issues - Part 2 (The End) | Main | The Need for Speed - ABCWebTest is now FAST! »
May 05, 2006
NUnit "Quick and Dirty" Tutorial
In the style of the JUnit Quick and Dirty Tutorial, here's a similar tutorial for NUnit. I'm assuming that you're familiar with C#/.NET, downloaded NUnit and have a development environment all setup for compiling and running C# code.
Preparing an NUnit test class
1. create a blank C# file (e.g. FooTests.cs)
2. import the following namespace:
using NUnit.Framework;
3. create a stand alone class that uses the "TestFixture" attribute (e.g. [TestFixture] public class FooTest { })
This is all that's required to setup your class for NUnit tests - fewer steps than for JUnit, in fact. Now you're ready to actually write some tests.
Writing an NUnit test
1. For every test you'd like to run, create a public method that returns void, takes no arguments and uses the "Test" attribute e.g. [Test] public void MyTest() { ... }
Unlike JUnit, there is no need to have the method start with "test" because the "Test" attribute tags the test so that NUnit knows that's your test case.
2. Instantiate the object you'd like to test inside the test method from the previous step.
Foo foo = new Foo();
3. Invoke the method(s) you'd like to test and assign the return values to local variables.
e.g. int actualValue = foo.bar(1, 2, 3);
4. Check the method's return value by using one of NUnit's assert methods. You can get a list of all the assert methods from the NUnit Documentation.
e.g. Assert.AreEqual(4, actualValue);
Initializing and De-initializing Tests
Often, you'll need to initialize or de-initialize a group of tests in the same way. For example if all your tests had to start with the same object creation, you can place that common initialization code into a special NUnit method with the "SetUp" attribute. Similarly, if all your tests had to do the same de-initializing steps, that code can be placed into a method tagged with the "TearDown" attribute.
Your test methods would then not have to perform those common steps anymore and could start with the "meat" of their testing.
The set up and tear down methods can have any name (unlike JUnit which requires they be called setUp() and tearDown(), respectively. Also, these methods don't need to be protected like in JUnit but can be public. If you don't have any use for them, don't include them and by default there will be no set up and tear down.
e.g.
//foo variable should be declared as an instance of the test class
[SetUp] public void SetUp() { foo = new Foo(); }
[TearDown] public void TearDown() { foo.cleanUp(); }
NUnit also has a nice once-only initialization/de-initialization feature where you can do an initialization once before any tests are run (instead of once before every test is run) and once after all tests are run (instead of once after every test is run). Use the "TestFixtureSetUp" and "TestFixtureTearDown" attributes, respectively, like so:
[TestFixtureSetUp] public void TestFixtureSetUp() {
//...
}
[TestFixtureTearDown] public void TestFixtureTearDown() {
//...
}
Grouping Your Tests Into a Suite
You can have a master suite test file that is a collection of all your unit test classes. This is another stand alone C# class that's tagged with the "Suite" attribute. Here's a sample of how it would look like:
using NUnit.Framework;
using NUnit.Core;
namespace ABCWebTest.Tests {
public class AllTests {
[Suite] public static TestSuite Suite {
get {
TestSuite suite = new TestSuite("All Tests");
suite.Add(new AjaxTests());
suite.Add(new BrowserTests());
suite.Add(new BrowserUtilityTests());
suite.Add(new KeyboardTests());
suite.Add(new MouseTests());
suite.Add(new PopupTests());
suite.Add(new SpeedTests());
suite.Add(new TextTests());
suite.Add(new TimerTests());
return suite;
}
}
}
}
Rules of Thumb
These are general guidelines to keep in mind as you're creating more tests with NUnit.
1. Create a single test class for each application class you have.
2. Name each test class the same name as the application class its testing but with "Tests" appended to the end. So if you have an application class called "ShoppingCart.cs" the test class would be called "ShoppingCartTests.cs"
3. Give meaningful names to each test method. I usually name the test method the same name as the method that its testing with some additional info appended to the name. For instance if I'm testing a method called "add" in my ShoppingCart class, I'll create a few test methods to test different ways of adding to a shopping cart:
- [Test] public void Add_SingleProduct() { ... }
- [Test] public void Add_MultipleProducts() { ... }
- [Test] public void Add_InvalidProduct() { ... }
- [Test] public void Add_Null() { ... }
4. The scope of how much checking to do in a single test case (test method) is a judgement call. I usually stick to a single method call with a single set of arguments, but you can stuff a single test case with multiple method calls and assertion checks. In the example above, that would mean creating a single Add() method and testing adding a single product, multiple products, invalid product and null all in one test method.
5. You can use the NUnit console or NUnit GUI to run your tests. The console I find is quicker. I usually use NAnt to run my NUnit tests from the console but I also find it convenient to use the NUnit GUI when I want to run a subset of my tests. Keep in mind, though, that the NUnit GUI uses the GUI thread as the main thread so tests aren't run in the main thread. This may cause issues if your code expects to be running in the main thread - I learned this lesson the hard way.
Posted by Misha Rybalov at May 5, 2006 06:00 PM