NUnit...
NUnit is an indispensable tool for automatically testing .NET applications. It's a tool for test-driven
development in .NET.
By: Melwyn D'Souza and Sarvesh Damle
Date: June 8, 2004
Download the code.
br>
NUnit is an indispensable tool for automatically testing .Net applications. It's a tool for test-driven
development in .NET. The primary goal of unit testing is to take the smallest piece of testable software in
the application, isolate it from the remainder of the code, and determine whether it behaves exactly as you
expect. Each unit is tested separately before integrating them into modules to test the interfaces between
modules. Unit testing has proven its value in that a large percentage of defects are identified during its use.
Use of NUnit?
NUnit does become a problem if you are trying to test your ASP.NET code. Not the middle-tier logic you tie into,
but the .aspx pages themselves. How can you test that the UI reacts to the user correctly? That the postback
events happen in the right order? That the correct next page is loaded after the user completes the page?
Testing these things requires that your code is running inside the ASP.NET worker process. Your pages need
access to the HTTPContext, the Request and Response objects, everything else that ASP.NET provides them at
runtime. If you attempt to test your compiled .aspx pages directly from the NUnit test runner, none of them will even load, let alone pass your tests.
NUnit has quickly become a general practice (standard) among the product team where more developers, PM and
testers have been pushing for this alternative. NUnit attributes can be extended by writing custom attributes
by developers and testers.
The advantages of using NUnit in normal testing scenarios are:
- With minimum code, testers can acquire coverage on applications with an instrumentation tool.
- A suite of NUnit unit tests can set the minimum requirement for a code's minimum functional screening;
therefore, this ensures that tester will not spend time on a broken build.
NUnitASP - The Solution
The typical attributes of the NUnit application are as follows:
NUnit uses attributes to mark the test code. Test code consists of:
- Test Suites
- A collection of test cases related to a single functional unit
- A collection of test fixtures supporting those cases
- Test Fixtures
- A collection of shared resources required for a given set of test cases
- Test Cases
- Should test one unit of functionality
The typical flow of writing of Unit test case is as follows:-
Step 1. Create a Class
- Mark it with [TestFixture]
Step 2. Add SetUp and TearDown
- Create new methods marked with [SetUp] and [TearDown]
- SetUp called before every test method
- TearDown called after every test method
- Used to create environment for tests to run
Step 3. Add a Test Case
- Add new method marked with [Test]
- Add logic to test expected and unexpected usage of target unit
- Can mark test method with [Ignore(�SOME_REASON�)]
Step 4. Use Assertion to test conditions
- Use the Assertion object to test runtime conditions
- Assertion.Assert
- Assertion.AssertEquals
- Assertion.AssertNull
- Assertion.AssertNotNull
- Assertion.AssertSame
Test for Expected Errors
- Some tests can be expected to generate thrown errors
- Use [ExpectedException(typeof(�SOME_EXCEPTION_TYPE�))]
You could write up a bunch of mock objects to convince your pages that they are really running in ASP.NET.
However, that list would include:
- The page "intrinsics": Request, Response, Application, Server, and Session
- The webcontrols: TextBox, Button, DropDownList, etc.
- The context: HTTPContext
You would spend much more time writing this mock framework than writing any unit tests for your own application.
NUnitASP, an open-source (MIT license) application, provides this framework for you. Or, more to the point, it
let's your pages run in the actual ASP.NET worker process, but allows you to create a mock fa�ade container to
test the UI with. This fa�ade creates all the server-side web- and html-control objects present on your page,
whose properties you can manipulate and whose events you can fire. Then, you can check the results (of a
postback or cross-page navigation).
To allow for this testing, NUnitASP has to provide not only a mock container for your pages but a browser
imitation object that acts as the requesting client. The browser imitation object is what allows you to test
the current URL, the cookies collection, and the static HTML output of a request. The collection of mock server
controls allows you to manipulate and test the server-side properties and behavior of your pages.
The code being tested is loaded into its own application domain. Thus, the NUnit tool can load and reload the
.NET assemblies you are testing without restarting the NUnit tool. In NUnit version 2.0 it looks for changes to
the test assemblies and will reload them automatically to ensure that the latest binary assembly is being
tested. This means you can perform code and test development cycles, running NUnit with loaded assemblies to
be tested after each compilation without restarting and loading test fixtures.
The benefit of NUnit is that it integrates easily into unit testing and .NET in general, and is an excellent
tool for system and regression testing. With the simple pass-fail user interface, there is no mistaking tests
that failed and tests that passed. Because tests are written in .NET, analysts, programmers, and testers can
codify tests and capture them as simple .NET algorithms that can be ascertained to validate the business rules.
How to implement a Test?
You need to download the NUnitASP (
http://nunitasp.sourceforge.net/download.html ).
To start using it, create a new ASP.NET Web Application project and add references to nunit.framework.dll (in
the NUnit install's bin folder) and nunitasp.dll (in the NUnitASP install's bin folder).
NUnit provides a common tool for testing. Analysts can write both positive and negative test cases, which can
be captured and codified in .NET by programmers who did not write the code, and the code either passes or fails.
A second huge benefit is that the authors of the code can run the same tests during unit testing, getting a head
start on bug-free code. Now your testers get started writing tests about the same time your coders do.
To demonstrate how all of this can and will work, include a trivial Windows Forms application, a class library representing business rules, and a test assembly that uses NUnit.
Building Sample Business Rules
Test code needs to be in a .DLL assembly, which is representative of the middleware part of your code commonly
referred to as business rules. Because our emphasis is on testing, we can use just about any code, so I created
a Class Library project containing a class named Numerics. Numerics perform simple verbose addition for integer
and double numeric types (see Listing 1).
To create a negative test, I wanted to check overflow errors�when an arithmetic operation causes a number to
exceed its maximum value, for example, 3,000,000,000 assigned to an integer contains more than 32 bits. To test
an arithmetic overflow, I turned "Check for Arithmetic Overflow/Underflow" on in the Property Pages
Configuration Properties Build (see Figure 1).

Figure 1 Enabling checks for arithmetic underflow and overflow.
Listing 1: Sample business rules we will be testing with NUnit.
using System;
namespace MyNumber
{
public class Numerics
{
public static int AddTwoIntegers (int a, int b)
{
return a + b;
}
public static double AddTwoDoubles (double a, double b)
{
return a + b;
}
}
}
|
The code contains two static addition methods.
Building a GUI Application
For our purposes, the GUI simply demonstrates how to use the Numeric class and represents our presentation
layer. The form I created contained three Textbox controls, three labels, and a button. Enter two numbers in
each of the first two Textboxes, click the button and the result are shown in the third Textbox. The My Number
assembly is referenced by the Windows Forms application, and the Numeric is invoked in the following manner:
textBox3.Text = Numerics.AddTwoIntegers (Convert.ToInt32 (textBox1.Text),
Convert.ToInt32 (textBox2.Text));
Configuring NUnit
We now have some code to test. We will need to download and install NUnit and then build our test fixture. You
can download NUnit from http://www.nunit.org and use all the default values for installation. This will install
the source code and binaries in \\Program Files\NUnit V2.0 by default.
Implementing the Test Assembly
Writing the tests represents the new information for us, so we'll take our time here.
A test is implemented as a Class Library. The test library references your business rules code and invokes
operations on that code, just as your presentation layer will be doing.
The way that NUnit works is to load the test .DLL into an AppDomain object, relying on attributes and Reflection
to determine which code represents tests. What we must do is apply attributes that NUnit will be looking for and
write the tests appropriately. Listing 2 contains some tests I wrote for the MyNumber.Numerics, followed by an
explanation of each of the attributes and the way the tests were written.
Listing 2: Test fixture for MyNumber.Numerics.
1: using System;
2: using NUnit.Framework;
3: using MyNumber;
4:
5: namespace Test
6: {
7: [TestFixture ()]
8: public class TestNumerics
9: {
10:
11: //[SetUp ()]
12: public void Init ()
13: {
14: // Initialization for each test method here!!!
15: }
16:
17: [Teardown ()]
18: public void Deinit ()
19: {
20: // De-initialization for each test method here!!
21: }
22:
23: [Test ()]
24: public void AddTwoNumberPass ()
25: {
26: Assertion.AssertEquals ("Integer arithmetic passed",
27: true, Numerics. AddTwoIntegers (10, 5) == 15);
28: }
29:
30: [Test ()]
31: public void AddTwoDoublesPass ()
32: {
33: Assertion.AssertEquals ("Floating-point arithmetic passed",
34: true, Numerics. AddTwoDoubles (1.3, 2.5) == 3.8);
35: }
36:
37: [Test (), ExpectedException (typeof (OverflowException))]
38: public void AddIntegerFailed()
39: {
40: int a = 2147483647;
41: int b = 5;
42: Assertion.AssertEquals ("Integer overflow expected",
43: true, Numerics. AddTwoIntegers ((int) a, (int) b) > 2147483647);
44: }
45: }
46: }
|
NUnit attributes and classes that we will be defining are contained in
\\Program Files\NUnit V2.0\bin\NUnit.Framework.dll. We will need to add a reference to NUnit.Framework.dll and
MyNumber.dll�the code we will be testing. For convenience, I added a using clause to their respective namespaces
as well.
To indicate that a class is a test fixture, apply the TestFixtureAttribute to the class, as shown on line 7.
If you need initialization and deinitialization code, add two methods to the test fixture. I named
these Init and Deinit, but they can be anything. It is the SetUp Attribute�case-sensitive�and TearDown Attribute
that points NUnit at these two methods. It is important to note that each of these methods will be called once
before every method attributed with TestAttribute is called.
Next, we need some tests. Tests are adorned with the Test Attribute. Each test is a method that takes no
arguments and returns void. Reflection is used to invoke these methods. Technically, return values and
parameters can be invoked using Reflection; they would have to be contrived by NUnit because NUnit is running
the test. However, it isn't the test method you are testing; it is the code in the test method. Because you
write the test code, you can supply the arguments. I defined two positive tests AddTwoNumberPass and
AddTwoDoublesPass, on lines 23 through 28, and on lines 31 through 35, respectively. Each of these tests uses
the assertion class defined by NUnit. I invoked Assertion.AssertEquals on each of lines 26 and 33. The first
argument is a message; the second argument is the value returned by the third argument. For example, line 27
evaluates an Add equal to 15. This should return true. We could also have used 15 as the second argument and
the Arithmetic.Add method as the third, rewriting the lines 26 and 27 as Assertion.AssertEquals(message, 15,
Arithmetic.Add(10, 5)).
Lines 27 through 44 incorporate a second attribute: ExpectedException Attribute. Passing the type record of an
exception class, you can test to ensure that a test throws an expected exception. In the example, I intentionally
create an overflow condition and want to ensure an exception is thrown.
Running Tests
Running the tests couldn't be easier. Run the NUnit GUI (or console version) and open the assembly containing
the test fixture. Click the Run button. Tests that return Green passed, and Red indicates failed test (see
Figure 2).After you change your code, simply return to NUnit and run the tests again.

Figure 2 Green indicates a passed test, and red indicates a failed test.
The console version of NUnit can be managed with a .cmd or .bat file, running tests at some scheduled time
such as overnight or as part of a build process.
Where to Next
For more information on the full NUnitASP programming model, you can check out their API documents at
http://nunitasp.sourceforge.net/api.html. The model contains other mock server controls, including ones
for grids and tables which allow you to access their contents as arrays of objects. (Not all the WebControls
have had mock controls implemented for them yet. The product is still in development.)
You may download the code here.