One of the things that had always bothered me with
unit tests is its difficulty in testing user interfaces. In .NET, the event handlers are usually
private methods, hence inaccessible for a unit test. This forced me to remove all business logic
from the UI so I could write unit tests.
While I think it’s a good practice to do so; I still had some areas where
business logic was mixed with UI code. How
could I unit test this code?
I discovered NUnitForms, a library written by Luke T. Maxon, in early 2006 but didn’t pay
much attention to it. I revisited the
web site earlier this week and decided to try the latest version, NUnitForms 2.0 Alpha 5. I was
very impressed by its straightforward approach. Being an early adopter of TDD, I had no
problem understanding the examples. It
flows very well with the existing NUnit framework. You can add your [TestFixture()]
and [Test()] attributes to your class and methods. The only new prerequisite is that you must derive
from NUnitFormTest.
If you want to create a setup and teardown method for
each of your test, do not use the [SetUp()] and [TearDown()] attributes. This is very important and I didn’t figure
this out until I read the source code of NUnitForms. Instead, override the methods Setup() and
Teardown() in NUnitFormTest. These
methods will get called before and after each test. If you do use the attributes, your test won’t
work unless you explicitly call the base methods init() and Verify().
Here’s a quick example of a unit test using the
NUnitForms library:
Let’s say you have a form with one button and a
textbox on it. When you click on the
button, it puts the string “test” in the textbox. You would like to make sure that clicking on
the button puts the string in the textbox.
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using NUnit.Extensions.Forms;
[TestFixture()]
[Category("UI")]
public class FormTest : NUnitFormTest
{
private MyForm m_MyForm;
private ButtonTester m_ButtonTester;
private TextBoxTester m_TextboxTester;
public override void Setup()
{
m_MyForm = new MyForm();
m_MyForm.Show();
// Pass the name of your controls in the testers
m_ButtonTester = new ButtonTester("MyButton")
m_TextboxTester = new TextBoxTester("MyTextbox");
}
[Test()]
public void TestMyButton()
{
// Simulate a click
m_ButtonTester.Click();
// Validate the content of the textbox. Note that I am using the
// new constraint model in NUnit 2.4
Assert.That(m_TextboxTester.Properties.Text, Is.EqualTo(“test”));
}
}
If you want to convince yourself that the button was
really clicked, you can always run a code coverage tool around your test.
While my experience with NUnitForms is pretty limited,
I do see value in this library. I don’t
know how it would react with complex user interfaces but it looks
very promising. I would be very interested to hear about people who have used NUnitForms extensively to see how it works in big projects.