Getting started with NunitForms

 

Recently, I blogged about using NUnit and NUnitForms to test VS 2005 Windows Forms applications. I pointed you all at the NUnitForms website and promised to post more about getting started with NUnitForms.

 

After installing NUnitForms, you can use NUnitForms to make unit tests for a form or to make end to end scenario tests on an entire GUI application. The documentation for each class is adequate (usually installed under %ProgramFiles%\NUnitForms\NUnitForms v2.0 alpha5\Documentation.chm) but the documentation for getting started isn’t very detailed. Here’s an excerpt from the introduction on the NUnitForms homepage:

 

“NUnitForms is an NUnit extension for unit and acceptance testing of Windows Forms applications.

 

Now it is easy to write automated tests for your Windows Forms classes.

 

Your NUnit tests can open a window and interact with the controls. Your tests will automatically manipulate and verify the properties of the gui. NUnitForms takes care of cleaning up your forms between tests, detecting and handling modal dialog boxes, and verifying that your expectations for the test are fulfilled.”

 

 The Documentation link’s overview on the website is out of date since it is for version 1 which doesn’t work with VS 2005. We on the Solutions team are using version 2.0 (alpha 5). The basic classes are the same as version 1 but, unfortunately, the recorder function doesn’t work correctly.

 

Things you need to know:

  1. Your NUnit test fixture class must inherit from NUnitFormTest
  2. In addition to a reference to NUnit.Framework, you need a reference to NUnit.Extensions.Forms. For example:

 

using NUnit.Framework;

using NUnit.Extensions.Forms;

Namespace yourTestSuiteNameSpace

{

            [TestFixture]

    public class myGUITests : NUnitFormTest

 

  1. To test a form, you have to instantiate it and use Form.Show or Form.ShowDialog to display the form.

 

  1. You get access to a form’s controls using the various control tester classes in NUnitForms (e.g. ButtonTester, LinkLabelTester, CheckBoxTester, RadioButtonTester, ComboBoxTester, TextBoxTester, etc.). You can instantiate a test object using the control name and the form name as follows:

      ButtonTester buttonTester = new ButtonTester("button1", "MyFormName");

 

  1. If the form uses panels, you can get to internal controls of each panel using qualified control names as follows:

      CheckBoxTester uncheckBoxTester = new CheckBoxTester( "aPanelName.checkBoxName", "MyFormName");

            Or

             RadioButtonTester radioTester = new RadioButtonTester("mainFormControlName.panelName.radioButtonName", "MyFormName");

            Hint: When you use checkboxes, use the Click method to check or uncheck the box. Using the test classes Checked attribute doesn’t trigger the event.

 

  1. All control tester classes inherit from the ControlTester class. You can use the ControlTester class directly for any type of control that doesn’t have its own tester class.

 

  1. You can also create your own custom test classes by inheriting from the ControlTester class and adding convenience methods like those in the other classes. For example, there’s no test class for rich textbox controls. So, I made one with the same convenience methods that are in the textbox tester class.

 

  1. If your test uses ShowDialog or the form you are testing launches other forms or message boxes, you have to tell NUnitForms what forms to expect and provide a “public void” method with test logic for that form:

 

      [Test]

   public void TestOKButtonTest()

   {

      ExpectModal("FormName", "formNameHandler");

            FormName form = new FormName();

form.ShowDialog();

            …

            public void formNameHandler ()

        {

          ButtonTester buttonTester = new ButtonTester("okButton", " FormName");

            // Check the OK button's text and then click it

            Assert.AreEqual("OK", buttonTester.Text, "FormName’s OK button text is wrong '" + buttonTester.Text + "'");

            buttonTester.Click();

        }

 

 

  1. If your test is expecting a message box, use the caption for the form name:

      ExpectModal("messageBoxCaption", "messageBoxClickerMethod");

 

  1. If you’re testing a form that uses threads, you need to do things a little differently! You’ll need a delegate added to the form that will call your test logic when the form is ready. You still need to use the ExpectModal call but the handler will be empty and the test logic for the form will be in the method that your test adds to the list of event listeners for the delegate. For example, when testing such an application, I did something like this when testing its main GUI form:

 

      public void genericFormHandler()

        {

            // Do nothing in this method!

 }

      [Test]

     public void MainFormTest()

{

MainGUIForm mainForm = new MainGUIForm();

            mainForm.OnFormReady += new EventHandler<EventArgs> (mainFormTestLogic);

          ExpectModal("MainGUIForm", "genericFormHandler");

mainForm.ShowDialog();

}

public void mainFormTestLogic (object sender, EventArgs e)

 

  1. Although the documentation may be lacking, there are a lot of useful examples in the NUnitForms tests. Download the source for version 1.3.1 (Version 2 source hasn’t been released yet) and use it as a reference on how to use various test classes or how to develop your own test classes for custom controls.