NUnitForms: ExpectModal and MessageBoxTester

April 10, 2005

My application doesn’t want to leave anymore! I’ve seen this bug two times in two weeks, so I decided to write a non-regression test for this very simple thing, which quickly has very bad effects as the user finally ends up killing the process manually.

I usually don’t write many tests for GUI and try to focus on the underlying code (model / services) instead, but sometimes it’s really helpful. Here I’ve got a Form which asks for confirmation to the end-user, using a MessageBox.Show call:

public const string ConfirmationDialogName = "Exit?";

private void MainForm_Closing(
    object sender, 
    CancelEventArgs e)
{
    DialogResult result = MessageBox.Show(
        "Do you really want to leave?",
        ConfirmationDialogName,
        MessageBoxButtons.YesNo,
        MessageBoxIcon.Question);
    if (result == DialogResult.No)
        e.Cancel = true;
}

I’ve extracted the MessageBox name to be able to tell NUnitForms how to recognize the modal window which will open.

Now to the tests: here I inherit from NUnitFormsTest which provides some useful services such as an ExpectModal method, and I setup two tests:

  • one to check that answering Yes will really close the form
  • another one to check that answering No will leave the form opened

The two tests call ExpectModal(string modalDialogName, string modalHandler) to specify which modal dialog is expected and to specify a handler which will respond to it. Those “expectations” are automatically verified at teardown.

using System;
using Library;
using NUnit.Framework;
using NUnit.Extensions.Forms;

namespace Tests
{
    public class Tests : NUnitFormTest
    {
        MainForm form;

        public override void Setup()
        {
            base.Setup();
            form = new MainForm();
            form.Show();
        }

        [Test]
        public void CancelExitShouldNotExit()
        {
            ExpectModal(
                MainForm.ConfirmationDialogName,
                "ConfirmModalByNo");
            form.Close();
            Assert.IsFalse(form.IsDisposed);
        }

        [Test]
        public void ConfirmExitShouldExit()
        {
            ExpectModal(
                MainForm.ConfirmationDialogName,
                "ConfirmModalByYes");
            form.Close();
            Assert.IsTrue(form.IsDisposed);
        }

        public void ConfirmModalByNo()
        {
            ConfirmModal(
                MessageBoxTester.Command.No);
        }

        public void ConfirmModalByYes()
        {
            ConfirmModal(
                MessageBoxTester.Command.Yes);
        }

        public void ConfirmModal(
            MessageBoxTester.Command command)
        {
            MessageBoxTester tester =
                new MessageBoxTester(
                    MainForm.ConfirmationDialogName);
            tester.SendCommand(command);
        }
    }
}

The ability to test modal dialogs programmatically is really valuable for non-regression testing of Windows Forms applications.