Tuesday, November 11, 2008

Testing the Impossible: User Dialogs

How do you test a user dialog like "Do you really want to quit?"

This code usually looks like this:

    public void quit () {
        if (!MessageDialog.ask (getShell(),
            "Really quit?",
            "Do you really want to quit?"
        ))
            return;

        ... quit ...
    }

The solution is simple:

    public void quit () {
        if (askToQuit ())
            return;

        ... quit ...
    }

    /** For tests */
    protected boolean askToQuit () {
        ... ask your question here ...
    }

In test cases, you can now extend the class, and override askToQuit:

    public boolean askToQuitWasCalled = false;
    public boolean askToQuitResult = true;

    protected boolean askToQuit () {
        askToQuitWasCalled = true;
        return askToQuitResult;
    }

Now, you can find out if the question would be asked and you can verify that the code behaves correctly depending on the answer. Tests that just want to quit won't need to do anything special to get the desired behavior.

The same applies to more complex dialogs: Refactor them to put their data into an intermediate structure which you can mock during the tests. That means to copy the data if the dialog is a black box but that's a small price to be paid for being able to test modal user dialogs.

Lesson: You don't want to test the dialog, you want to test whether it is opened at the right place, under the right circumstances and if the result is processes correctly.

No comments: