Developing Automated Tests Using NUnit and VB.NET
|
|
Abstract
This article describes how to write unit tests in Visual Basic .NET using the
market standard automated unit testing tool NUnit 2.0.
What is NUnit?
NUnit is a unit testing framework that has been ported from JUnit. It is a free
tool, with source code freely available, and is written in C#.NET. It supports
unit tests written in any .NET language. For more information see
http://www.nunit.org
.
Why write Automated Tests?
Writing automated tests provides many benefits:
-
It’s quicker to develop: You write high quality code quicker. This
is because you continuously regression test your code and spend less time
manual testing.
-
Refactoring: Refactoring is a term used when you change the code
base without changing the functionality of the code. Refactoring is essential
to ensure code does not rot, particularly in an iterative type phased
development environment. If you have a suite of tests you can refactor as much
as you like, provided all the tests still pass. Refactoring without automated
tests is suicide.
-
Exhaustiveness: Every time you change the code, it is fully tested.
Developers normally do not test all their code. It is boring. They just don’t.
With a full suite of tests they can ensure that everything works again and
again. They can then get on with writing more code, rather than debugging and
fixing previously written code.
-
Repeatability: All tests get run every time. None get missed out.
-
Documented: The test code itself is the documentation.
-
Standard: Because the tests use a standard anyone can run them. We do
not loose knowledge when people leave.
Using NUnit 2.0 – An Example
In this example we will do the following:
1. Create a solution in VS.NET for your code project and the test project.
2. Set up the Test class.
3. Write a basic test.
4. Write an exception type test.
5. Run the tests using the NUnit UI.
Preliminaries – The Account Class
Throughout this example I will use our old friend the Account class for the
example:
The rules of the Account class are as follows:
1. Overdraft limit must be positive.
2. Amount withdrawn or deposited must be greater than zero.
3. Cannot withdraw over the overdraft limit.
[Note that these rules should normally be written as a set of pre and post
conditions together with the class invariants. This is called Design By
Contract and is not within the scope of this article. To find out more about
DBC go here
.]
Preliminaries – Download and install NUnit
NUnit can be downloaded from http://www.nunit.org
Download the MSI and run it. NUnit should be installed into the C:/Program
Files directory. If you are working within a team environment, I would suggest
everyone installs it in the same directory.
Step 1: Creating an NUnit VB.NET set of tests.
1. Create a blank solution in VS.NET. This will contain the code you are
testing and a set of tests.
2. Add the project containing the code which you are going to test.
3. Open VS.NET and create a new VB.NET class library.
4. Name the library {project name to be tested}NUnitTests.
5. Add a project reference to the project you are going to test.
6. Add a reference to the NUnit framework, in the location C:\Program
Files\NUnit V2.0\bin
7. Add a new class to your test project called {class to test}Tests.
The solution explorer in your IDE should look something like this:
Step 2: Set up the Test class.
At the top of the class you need references to the assembly you are testing,
and also to the NUnit framework. Thus, you need the following Imports
statements:
Imports
System
Imports
Accounting
Imports
NUnit.Framework
[I have an Imports System statement here as I prefer to remove all the
automatic ‘imports’ that VB does for you in the project properties. I’d rather
have everything visible at the top of my classes than have to search around.
This is also more compatible with C# syntax. It’s a personal choice.]
You class now needs an attribute of TestFixture. This tells the NUnit framework
that this class is a set of tests that can be run by NUnit. NUnit uses
Attributes to pick out what it needs:
<TestFixture()> _
Public Class
AccountTests
End Class
Before each test is run there will be a standard set of things you might want
to set up and then tear down after each test. In my Account example, I want an
account set up with an overdraft limit set. NUnit caters for this using the
SetUp and TearDown attributes. E.g.
<TestFixture()> _
Public Class AccountTests
Private mAccount
As Account
<SetUp()> _
Public Sub SetUp()
mAccount = New Account(1000)
End Sub
<TearDown()> _
Public Sub TearDown()
'nothing to go here
End Sub
End
Class
Now it is time to write the tests.
Step 3: Write a basic test.
Each test is written as a Sub in VB.NET. We tell NUnit it is a Test by using
the Test attribute, like this:
<Test()> _
Public Sub AccountWithdraw()
End Sub
Now we write a test inside the Sub. For this test, I wish to test that I can
withdraw an amount from my account provided it is within the overdraft limit.
Thus,
Public Sub
AccountWithdraw()
Dim BalancePre
As Double
BalancePre = mAccount.Balance
mAccount.Withdraw(200)
Assertion.Assert(mAccount.Balance =
BalancePre - 200)
End Sub
I’m using the NUnit Assertion object here to make an assertion about what
should be correct after I’ve run some action on my target code. The Assertion
object has many useful operations. I’ve leave you to find out what they are.
The next topic to consider is how to write a test where you wish to ensure that
your code is raising exceptions correctly.
Step 4: Write an exception type test.
To test exceptions we use the ExpectedException attribute that comes with the
NUnit Framework as follows:
<Test(),
ExpectedException(GetType(ArgumentOutOfRangeException))>
_
Public Sub TestWithdrawNegativeAmount()
mAccount.Withdraw(-100)
End
Sub
Step 5: Run the tests using the NUnit UI.
To run the tests, open up the Project Options for the Test project and set the
following options in the Configuration Properties\Debugging section:
Start External Program: C:\Program Files\NUnit V2.0\bin\nunit-gui.exe
Command Line Arguments: /assembly: {Full path of assembly} [E.g.
/assembly:C:\Data\NUnit\Account\Account.NUnitTests\bin\AccountingNUnitTests.dll]
Now set the Test project as the Start Up Project, by right clicking on the
project.
Now build and run the project. You should see the following UI appear:
Click the Run button to run your tests. If they pass then you will see green
lights. If they fail you will see a red light. If no assertions have been run
you will see an amber light.
When you get red lights you can set breakpoints and step into your code and
debug away.
What Should You Write Tests For?
Here’s a common sense set of guidelines:
-
Write tests for things which you think are likely to be changed, or have a
chance of failing.
-
If the test takes no time to write (a few minutes) then there is no harm in
writing it.
-
If a test takes a day or so to write, then think about whether you really need
to write the test.
-
If a test takes a few hours to do manually, and you know you will have to do it
more than once, then write a test for it, even if it takes a day to do so.
-
If you get a bug reported, then write a test for it and make sure it fails.
Then you carry on coding until it passes and everything else still passes. Give
the test a name that refers to the bug. This way you can ensure you get no
repeat bugs. Repeat bugs in your code are shooting offense!
|