Test-Driving X11 GUIs
by George Nistorica
|
Pages: 1, 2, 3
Writing GUIs for Testability
Having in mind the strengths and weaknesses of X11::GUITest, it's critical to design graphical user interfaces that are easy to test. This way, you shorten your maintenance time, as you can have a tester program that can help check that the GUI hasn't lost some of its windows in the development/maintenance process.
Of course, when displaying a license text when your GUI starts, you don't have the means to check that the contents are unchanged using X11::GUITest.
What you can do is to ensure that all child windows are "in place" and that a user can access them in the same way as he/she could in previous versions.
If you define ways of navigating the GUI using keyboard shortcuts so that you can reach any "leaf" window starting from the top-level window, then it's trivial for a test program to navigate the same way you do and ensure that all windows are reachable as they were in previous versions.
Consider the following code based on the tested Tk program:
$menu{'OTHER'} = $menu_bar->cascade(
-label => 'Other',
-tearoff => 0,
);
$menu{'OTHER'}->command(
-label => 'Editor',
-command => sub {
edit_window();
}
);
It defines a piece of menu from the overall menu of the application. As you may notice, there are no keyboard shortcuts that you can use to access the Editor window.
Thinking of testability, you could go to some lengths to test this piece of code to ensure that the Editor window is reachable and that it indeed pops up. You could record the application's position on the screen and then click the Other button, then move the mouse over the Editor button and click it. I'm sure you can spot some caveats here, among them:
- You need to make sure that the application is always on the screen at some known coordinates (use
GetWindowPos()) or maybe that the test always moves the window to the same place (useMoveWindow()). - You have to take into consideration font size changes, localization, and resolution changes so that you are sure you are clicking in the right place.
This kind of testing is fragile and error-prone. You can make things simpler and more robust: add keyboard shortcuts for each action. You gain two main benefits: you make some users (like me) happier and ease the testing process. You just need to define all the "paths" that you need to "walk" and define the child window titles so you know you've reached them.
Here's a slight adjustment to the tested application so that it provides keyboard shortcuts:
$menu{'OTHER'} = $menu_bar->cascade(
-label => '~Other',
-tearoff => 0,
);
$menu{'OTHER'}->command(
-label => '~Editor',
-command => sub {
edit_window();
}
);
sub edit_window {
# some initialization code here ...
$edit_window = $main_window->Toplevel();
# Set the title of the Editor window
$edit_window->title("This is an edit window");
# the rest of the code here ....
}
This piece of code is easier to test. Navigate the application until you reach the Editor window:
SendKeys('%(o)e');
Now you should have the Editor window spawned. Grab a list of windows having the title matching the Editor window's title:
@edit_windows = FindWindowLike( $edit_title );
Check to see whether the Editor window is present. Also, there should be only one Editor window started:
if ( @edit_windows == 1 ) {
# code here
} else {
# we have zero or more than one Editor window, so something is not quite
# right
}
This kind of code is easy to extend, as you can store the application window hierarchy in some external file outside of the program source (in some sort of markup language file, or anything that suits your needs). Having this external definition of the windows' hierarchy and their properties, the tester program can read the same file the tested application uses; thus, both know the same keyboard shortcuts and window titles.
Program logic errors and/or bugs in underlying libraries used are easier to catch before you release the software.
Conclusion
As you can see, there is no easy way to test an entire GUI application with X11::GUITest, but you can test the important parts. Also, for some actions you can use a mixed approach, such as initiating an event using the application interface (connecting to a remote server protected with a user/password auth scheme) and picking the results from a log file.
While the testing done in the previous paragraph is necessary, it is not sufficient. It would be great if there were someone willing to pick up the module and research whether it could be possible for X11::GUITest to be able to fetch data from the widgets, making it possible to "read" the contents of a window (from a text widget, for example).
This kind of testing is more complete than simply driving the GUI.
Of course, you could also use X11::GUITest to write a "record and playback" application. You might only need GetMousePos(), IsMouseButtonPressed(), and the other mouse functions. As I said earlier, in my opinion this kind of testing is too fragile.
The problem is that you can't validate the contents of the windows.
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 1 of 1.
- It's not X11 that's the problem.
2006-08-12 06:11:40 ralph@inputplus.co.uk [Reply]
Those of us involved in X11 GUI testing before Firefox, GTK+, etc., know that X11 and the Xt Widget framework, upon which the Athena and Motif widget sets were built, supported getting and setting the attributes of widgets.
To see this today, start xmag, then start editres. Do Commands -> Get Tree and click on the xmag window. Select pane2's `new' button, then Commands -> Show Resource Box. This shows you all the attributes of the widget. Select `label' with mouse button 2; the text `new' will appear at the bottom. Alter it to `get' and hit Apply; the xmag's window alters to have a `get' button instead.
This shows the interface is there for a decent GUI tester, it's just GTK+, etc., chose not to provide this interface or anything like it.
Cheers,
Ralph Corderoy.



