Test Driven Development Using NUnit in C#By Muthukumar. V
Testing during development is one of the basic tenets of eXtreme Programming (XP). Another proposition of eXtreme Programming is automation of every possible, repetitive task. This is because automation improves productivity to a very large extent. Put these two tenants together and you have the bedrock for an increasingly popular design methodology: Test Driven Development (TDD).
The most enjoyed phase of software development will always be Design and Coding, while the most hated parts of software development will always be bug fixing. Just ask yourself - would you rather be designing a system and/or writing the code, or would you rather be picking through an application and running tests, trying to squash a bug? Regardless of how unenjoyable testing and bug hunting are, they are necessary steps in the creation of an application. Despite how good of a programmer you may be, you will still produce bugs somewhere along the line.
A number of different software development methodologies have been proposed to reduce the amount of bugs in code. To understand the effects of bugs that creep up during the design process, realize that:
- One bug in code is equal to only one bug - though fixing it might produce more!
- One bug created in the design phase is equal to more than 10 bugs in the coding phase
- One bug created in requirement phase is equal to more than 100 bugs in the coding phase
Test Driven Development, Unit Tests, and NUnit, Oh My!
When sitting down to create an application, many developers start by writing the code. Test Driven Development emphasizes the opposite, stressing the need to prepare test scenarios or test cases before writing the code itself. This seemingly backwards approach has some benefits. First of all, it requires that the programmer be very clear about what tests the program should pass and what test it should fail, bringing such concerns to the forefront of the software design process. Furthermore, by meticulously detailing what tests a system should pass and fail we can use tools to automate most of our tests. An automated job is one that's always very, very easy to do. These automated tests are meant to be run every time there's a code change and are referred to as unit tests.
NUnit is a free, open-source tool for .NET that is developed as a framework which can help automate unit testing. (The same unit test framework was already available for Java and was named jUnit.) NUnit can be downloaded from NUnit site or the SourceForge NUnit page.
Installation and Setup of NUnit
After downloading the NUnit from either of the above download pages, run the installation program,
NUnit-XXX.msi. At the time of this writing, the current version of NUnit is 2.2.0 and the setup file name is
NUnit-2.2.0.msi. This setup will install the required libraries.
NUnit provides two utilities which can be used for running automated tests:
nunit-gui.exe, a GUI tool which I most commonly use, and
nunit-console.exe, which is a console program
nunit-gui.exetool. This can be run from Start Menu --> Programs --> Nunit --> NUnit GUI. After opening the tool, click on the File --> Open and open the
C:\Program Files\NUnit 2.2\binfolder. (The folder could be different if the installation has happened by choosing a different folder.) When the DLL is chosen, NUnit-GUI shows all the unit test code written for the particular DLL using the NUnit framework. If the button Run is clicked, it will show the results as follows.
- Passed Test - Green color
- Failed Test - Red color
- Ignored Test - Yellow color
nunit.tests.dllDLL contains over 600 tests and when run all of them should pass and turn the color to Green, as shown in the screenshot below. This means our installation is properly complete.
Using NUnit to Apply Unit Tests in a Visual Studio .NET Project
In order to run test cases we'll need to things:
- The test cases themselves, and
- The program that is having test cases run against it
The sample application is a command-line application with a single class,
has three properties:
CashBalance, along with a method,
which debits amount from the person's
CashBalance. The germane code is shown below:
Ideally we wouldn't yet have written the code for the
Person class. Instead, we'd just have documentation
that described the behavior of the
Person class. This behavior might be spelled out as follows:
- A person has properties to access their age, full name, and cash balance.
- When instantiating a person, we should be able to provide the first and last name, along with the age.
- The person's full name property should return the specified first and last names with a space in-between.
- When instantiating a person the cash balance should be 100,000.
- The cash balance should be reduced by the amount spent on car purchase.
- If we create a person with first and last name of "John" and "Abraham," and age 10, the person's full name should not be "John Smith"
- This person's full name should be "John Abraham"
- This person's age should be 10
- Before purchasing a car, this person's cash balance should be 100,000
- After buying a 20,000 car, the person's cash balance should be 80,000
[TestFixture]attribute. This class will contain all the relevant tests to test the methods, operations, and values in the
[TestFixture]class will also contain the capability to initialize, instantiate and operate on our methods and classes to be tested. This test class will look something like:
The test class can contain a method that sets up the test run. This method should be marked with the
attribute, as shown above. Usually class instantiations, initialization of variables, etc., are performed here.
Each test case you want to run should be a
public method marked with the
[Test] attribute. Inside the test cases you'll commonly find
Assert statements that test for
equality or Boolean conditions. Some of the methods available in the
Assert class include:
IsNull(), and so on.
The class also has some more utility functions like
Ignore(), which can be used for
custom error case generations. For more information see http://www.nunit.org/index.php?p=assertions&r=2.2.
NUnit has more attributes that just
[Test]. Attributes like
[Explicit], and others
add some value to the testing process. For more details about these attributes see http://www.nunit.org/index.php?p=attributes&r=2.2.
The following code shows example setup and test case methods for the
Note that in the test class we have
using NUnit.Framework;. You must also add the
C:\Program Files\NUnit 2.2\bin\nunit.framework.dll
assembly to the application's References folder. (Right click on the References folder in the Solution Explorer, choose Add,
and navigate to the appropriate assembly.)
Running the Test Cases
The final step is to run the test cases we just created. To do this, launch the NUnit-GUI tool, go to the File menu and select Open. Next, browse to the EXE file for the sample application. This will then load the test cases in the NUnit-GUI tool, at which point we can click the Run button to begin the tests. Ideally, all test cases should pass, as shown in the screenshot below:
These test cases should be run after ever major code change. In fact, NUnit can be run from the command-line, meaning that you can include unit test case running as one of the steps in your application's build process.
Conclusion and More Information
In this article we took a look at Test Driven Development (TDD), unit testing, and NUnit, seeing how easy it was to create automated tests through the help of NUnit. At this point, however, you may be wondering how unit testing could help an ASP.NET application. Unit testing with NUnit is useful for testing class libraries that makeup an ASP.NET application, but is not designed to test the UI portions of an ASP.NET application. There is, however, an additional free tool, NUnitAsp, that is designed to provide unit testing for the GUI portion of a Web application. We'll examine this in a future article!
I leave you with some resources one can get more information on Test Driven Development, Extreme Programming and related areas..
- There is a nice book by James Newkirk and Alexei A. Vorontsov titled Test Driven Development in .NET
- Introduction to Extreme Programming
- Rules and Practices of Extreme Programming
- Wiki resources on Test Driven Development and Extreme Programming
- Refactoring code - Another hot topic in eXtreme programming