Automated GUI Testing
by George Nistorica
|
Pages: 1, 2, 3, 4
Here's a sample routine that tester.pl uses:
sub bring_window_to_front {
my $window = shift;
my $success = 1;
if ( SetActiveWindow($window) ) {
print "* Successfully set the window id: $window active\n";
}
else {
print "* Could not set the window id: $window active\n";
$success = 0;
}
if ( SetForegroundWindow($window) ) {
print "* Window id: $window brought to foreground\n";
}
else {
print "* Window id: $window could not be brought to foreground\n";
$success = 0;
}
return $success;
}
In case you don't want to bring a window to front but expect it to be in
front, use GetForegroundWindow(). That way, you can just check the
return value with a window ID and find out if it is in front.
Key Pressing
You have found your window and have made sure that it has focus. What next?
It's time to send data to the window. This is the purpose of the
SendKeys() function. You can send to an application not only
basic keypresses, but combinations of keys too. Here's an example from the
tester.pl program:
my @keys = ( "%{F}", "{RIGHT}", "E", );
for my $key (@keys) {
SendKeys( $key, $pause_between_keypress );
}
The code starts with an array containing the keypresses. Note the format of
the first three elements. The keypresses are: Alt+F, right arrow, and E. With the
application open, this navigates the menu in order to open the editor.
For a full listing of "special" keystrokes or combinations of keys, consult the function's documentation.
Finding Text in Your Application
You may want to learn how you can "read" text written in GUI windows.
Unfortunately, you can't read everything. You can read the text
written in the title of windows (useful for identifying a window by its
title). You can also read text in Edit class windows; for example, the part of
Internet Explorer where you type in a URL, or the list items in a ListBox. There
may be other window classes from where you can fetch text; just verify with
WinSpy++ whether you can "read" from a window, before writing your program, in order
to avoid frustration.
Remember that you can't (at least now) read everything written in a window. Maybe a future version of Win32::GuiTest will provide a means by which to fetch text from a window, no matter what class that window is. In my humble opinion, it would be an awesome feature.
The two functions useful for grabbing text are GetWindowText()
and WMGetText(). Both take as a parameter the window ID:
$text = GetWindowText($window);
$text = WMGetText($window);
Pushing Buttons
Pushing buttons can be tricky. The syntax is
PushButton($button[,$delay]), and the variable
$button can be either the text of the button (its caption) or the
button ID. As Piotr Kaluski points out in "Be
Careful with PushChildButton," you sometimes want to specify a button ID,
but instead the function matches a button having text like the one you used in
the regexp. He posted a patch
to the perlguitest mailing list.
Also note that when using Tk, as I do in this example, you can't identify buttons by their text--you need to use their IDs (if you know them). With native Win32 applications, you can identify buttons by their text. To check the differences, use WinSpy++ to look at a Tk button's caption and a native Win32 button's caption.
Although PushButton() works fine on native Win32 buttons, I
couldn't make it work on my Tk application, so in tester.pl, I
use a trick in the push_button() subroutine:
sub push_button {
my $parent_window_title = shift;
my @button;
my @window;
SendKeys("%{F}");
SendKeys("O");
sleep 1;
@window = FindWindowLike( undef, $parent_window_title, "" );
if ( !bring_window_to_front( $window[0] ) ) {
print "* Could not bring to front $window[0]\n";
}
@button = FindWindowLike( $window[0], "", "Button" );
sleep 1;
print "* Trying to push button id: $button[0]\n";
PushChildButton( $window[0], $button[0], 0.25 );
sleep 1;
click_on_the_middle_of_window( $button[0] );
}
Notice that the function depends on the tested.pl application,
as it has hard-coded the way to spawn the Button window (by
navigating the menu using keystrokes). It is easy to adapt it to be more
flexible and to be less coupled with the rest of the code.

