Thursday 15 April 2010

NUnit Part 1: A Testing Framework For C#

So if you've read my last post (or if you've come across testing before) you'll hopefully be sold on TDD and Unit Testing. But how do we actually go about testing code in C#?

Most coders use a version of the XUnit framework to test their code. For C# this means NUnit. Simply download the installer, run it and add a reference to it in your project. In Visual C# Express, simply right click on your project, add a reference and browse to the NUnit\bin\net-2.0\framework folder. Add the nunit.framework dll and we're done (you wont need the other dlls until later). That was easy!

Now that our project knows where to find NUnit, we can write our first tests. For this example, we're going to start making a simple calculator in C#. Add a new class to your project called "Calculator_Tests". When I test a class called "X" I like to call the testing class "X_Tests". Normally I try to avoid using underscores in names, but I've grudgingly accepted the wisdom of this approach (we'll see why when we run our tests). Add the following to the class:



You'll need to replace WindowsGame1 with your projects name. The using statement lets the class know about NUnit. The [TestFixture] attribute tells NUnit that the class contains tests. Similarly, the [Test] attribute tells NUnit that it should run the following method. The Assert class is part of NUnit and is how we test results. It has many methods (AreSame checks if two references are actually to the same object, AreEquals checks their equality, IsTrue expects true statements etc...) The test passes if all its asserts pass. On the other hand, if even one assert fails so does the test.

Note the naming convention for the test. Once again we are using underscores. This is simply to make the results of our tests easier to read and is by no means required.

Now try to compile the project. Obviously we get some errors as we haven't written the Calculator class yet. But compile time errors are a Good Thing&trade. This way, we don't accidentally ship something that's broken. So lets add the minimum amount of code required to compile:



Again, you'll need to rename WindowsGame1 to your project name. Hit compile and we're done. Right? No? But according to the compiler our code is fine? Obviously our add method is wrong. To proove it lets run our test. Open up the NUnit gui and load our project (it should be in our projects bin folder - probably bin\x86\Debug\). Hit run and you'll see a big red cross next to our test name (see why the odd naming convention was recommended?) Hmm... lets fix that! Change our calculator class to:



Here we've demonstrated a key point about TDD - always do the simplest thing required to pass a test. Sure we'll miss some important boundary testing (null values etc...) but we can cover all that in our unit tests. For now, lets just get the code working!
Compile and run our test. Green light! So we're finished right? Well... not quite. We've still not done our refactoring yet. The problem is the unnamed constant (3). Unnamed constants are a Bad Thing&trade. Coders will often talk about bad smells - that is code that appears to work, but doesn't feel right - and an unnamed constant really stinks. But at least we have a fall back solution that we know makes our tests works. Lets try the (hopefully obvious) solution:



Compile, test and green light. OK, so we've not checked our boundry cases (for instance calculator.Add( int.MaxValue )) but for now we're good. We can improove our confidence in our method by adding to our smoke test:



Now we can delete the commented out line from the Add method. And we're finally done. Hopefully you've seen that tests are easy to implement (if a little pointless in this case) and that TDD can be quite painless. In the next example I'll show you how to reduce the amount of test code you have to write using the setup and teardown methods. Stay tuned.

No comments:

Post a Comment