Thursday, May 26, 2005

Win32::GuiTest

I have given laborious and painful birth to an automated GUI tester. I'm feeling a bit of postpartem depression, because it's nowhere near as clean as I'd like. I chose some complex ways of coding simply because the obvious ways produced errors or strange results that I didn't understand. It was also hard to get consistent results... things would stop and start working without apparent cause.

Bleh. I don't like programming voodoo.

This article says, "the first rule of GUI testing is: Don’t!", and it's really true. It would have been far better to get my developer to design his GUI app for testability in the first place, or at least get him to embed handy hooks in the code itself. Working totally from the outside, trying to write code that looks at and uses a GUI on the screen exactly as you do, is

But still, there are times when you do have to work as a complete outsider to the code. It is nice that there's a way, however painful. And here are some things I learned. Who knows if they will have any applicability to anybody else's Win32::GuiTest project? I'm sure it depends on a million quirks of the system you're testing.

1. Most things I saw on my screen could not be probed by Win32::GuiTest, as far as I could tell. About all I could see were the titles of windows and window elements, and not even all of those.
2. If you SendKeys, don't forget to bring your window to the foreground with SetForegroundWindow first. For me, the same GUI automatically seized the foreground on one machine, but on another machine, it stayed back, and the wrong window intercepted my keystrokes.
3. I wanted to know how long an hourglass wait lasted while a new window came up. I found no good solution. FindWindowLike succeeded too soon - it found the window immediately, long before the user could see it. What I settled for was to count the number of dependent items that GetChildWindows would find for the new window - and keep counting until the number was up to its maximum value. Then I knew the window was ready for business. Kludgey? Oh, yes!
4. Insert lots of sleep()s. They help reduce errors enormously.
5. I had trouble stringing several tests together into a single session. The first test in a single session would work fine, but inconsistent problems cropped up with subsequent tests. Eventually, I remembered that it's a machine and it doesn't get bored, so I made it close the application, get all the way out, and go all the way back in for each test.

No comments: