Just when I thought things were well under control in dotNetInstaller, someone filed this bug. It basically says that an installed check doesn’t work. This is pretty major functionality and I was under the impression that I unit-tested it in every possible direction. There’s at least a dozen tests that walk all kinds of scenarios around these checks and everything passes. It took ten seconds to find the culprit: the UI has a silly bug and such a check cannot be added to a configuration node. Naturally unit tests don’t use the UI. The user cannot take advantage of the functionality, even though the functionality itself … functions.
It’s a great example of total failure. Something has to be done.
Executing the Application
The first part of testing a UI is being able to execute and shutdown the application. Fortunately .NET has a very usable model for this.
Simple UI Tests
We can fetch the window title and test simple scenarios such as passing /? on the command line: the window title should be “Help”.
Hitting Menu Items
Getting the window title is nice, but I want to click through menus, or drag and drop stuff! After a bit of search I stumbled on the Microsoft UI Automation Framework in .NET 3.0. I had it running in half an hour and I am impressed. I’ll agree with James McCaffrey who writes in this post “I believe the development of the UI Automation library is one of the most important advances in test automation to date” and John Robbins who says in his article that this is the “realization of the dream of being able to automate the GUI portions of your application plus the guarantee that the playback would be exactly what you expected”. We’ve been doing this for web applications for ever, now this kind of robustness comes to Win32 forms and WPF applications.
I used these two articles to get started, so I’ll skip the how. Just read them.
I was too lazy to look at the code of the application I am testing, so I wrote something simple to dump controls. This gives a tree of controls that I can now fetch, use, etc.
Working with Menus
You can locate the application’s menu bar and each menu.
To click the File menu, you get a pattern that applies to menus and call a specific pattern method (for an ExpandCollapsePattern, Expand).
You can already see that this is becoming rather cumbersome. I would have to write a UIMenu and UIMenuItem class or it’s going to be a copy-paste exercise.
Someone must have had this problem before me. That someone is ThoughtWorks and they created White. White exposes a strongly typed and therefore less verbose and more usable object model for the UI being tested.
Clicking Through Menus
Clicking through menus with White, starting with the top-level application menu, could use a helper function. Each item needs to be clicked in order to fetch its children, collapsed menu items don’t have any.
Here’s how to use it:
Bug Solved and Unit-Tested
My original problem was a bug in dotNetInstaller where adding an installed check through the UI would popup an error. I was now able to write a unit test for it.