One of the things I've had the pleasure of working with for Mendeley is Hooq; Hooq is a GPL/LGPL-licensed system for testing Qt4 GUI applications, on multiple platforms (Linux and Windows being where most of the focus has been at the moment). It's mostly GPL, but an LGPL library is loaded into applications being tested, at runtime.
With apologies in advance for the incredibly unfriendly UI at the moment (patches welcome :p), here's a lots-of-pictures demonstration on using it to test a trivial application.
After building the demo application and Hooq, and running hooq, you'll get a screen like the following:
For organisation, Hooq uses the concept of a 'test set' - this can be one per application, tests for different areas of the same application, or whatever you choose. First, you need to create one - select "New Test Set..." from the file menu, and you'll get another ugly dialog:
After filling it in and clicking OK, you'll be back to the main screen, except that 'Test set' will be filled in (screenshot); type in 'Foo' in the box at the bottom, then click 'Record' (screenshot). The demo application will then start - if you type in "Hello, World" you should see something like this:
Click the close button in the window decorations, and the Hooq window will now have a test entry, with run and edit buttons:
After clicking on the edit button highlighted above, you'll get a script editor (Hooq uses QtScript for test scripts):
If you then click in the margin on the line after "QTextEdit_0.sendText(string0)", there'll then be a breakpoint marker on that line:
If you then click the run button in the toolbar, the script will stop running at that line:
At this point, if you click 'pick property' in the toolbar (new icons welcome), you can then click on any widget in the application being tested, and get a list of its Q_PROPERTYs:
For this example, scroll down to "plainText", and click compare; this will insert a check into the JavaScript code in the editor:
Remove the breakpoint, and run it a few times; it should repeat your input and quit each time, without an error; however, if you change the "string0" variable at the top from "Hello, World" to something else, like "Hello, World!", then click run, the test will error, if you don't also change the compare statement:
This is more useful when the test hasn't changed, but when the application itself has (i.e. a regression). Hooq also has a "Run All" feature, to run all the tests in a set unattended, and show a summary at the end.
As some more detailed information:
Hooq loads a shared library into the application being tested (via gdb under Linux, and a very ugly hack under Windows) which recieves every QEvent in the application, and sends user input events, encoded in XML, to a hooq client (the GUI client is shown above, but there's also a CLI one that just records and plays the XML data). In the GUI client, the XML is converted into a tree of sorts, and then a few modifications are optionally made (selectable via the "Options" menu):
These options are:
- Ignore Mouse Movements
- Don't create JavaScript code for mouse events, except where they end up creating drag and drop events.
- Simplify Mouse Movements
- Only available if the above is off; instead of creating code for every single 1-pixel mouse movement made, create simplified code, like "move in a straight line from (x1, y1) to (x2, y2) over 300 milliseconds"
- Simplify Strings
- Repeated keyPress/keyRelease events are composed into "sendText" events, which take a string parameter. Like the two above options, this greatly decreases the length, and increases the readability of the generated code.
- Use Variables For Strings
- Any string used by sendText is stored in a JavaScript variable, instead of being hardcoded every time it is used; this makes it easier to modify the script in the future.
- Use Variables For Object References
- This doesn't change the meaning of the code at all, but generally makes the code shorter.
- Include Raw XML as Comment
- Mainly useful for debugging; includes the raw XML code received over the socket as a JavaScript comment
- Ignore Qt Internal Widgets
- Qt in some circumstances (such as drag and drop under X11) automatically creates magic widgets; this option makes Hooq ignore them.