Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 44 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
44
Dung lượng
405,5 KB
Nội dung
Linköpings universitet
Institutionen för datavetenskap
Final Thesis
Communication Interface between Rational
Robot and Qt objects
by
Nasir Uddin Ahmed
LiTH-IDA-EX--03/078--SE
2003-12-17
Supervisor: Magnus Werner
Examiner:
Henrik Eriksson
Abstract
Automated black box, GUI-level regression test tools are popular in the industry.
Currently, IBM Rational Robot being one of the best testing tools supports wide verity of
integrated development environments (IDEs) and languages. Unfortunately it does not
support Qt, the multiplatform C++ GUI toolkit. The excellent documentation, clean
interface, and a sensible approach to the object oriented paradigm makes Qt one of the
most popular GUI toolkits in the world.
The project describes why Rational Robot cannot recognize the Qt objects and their
properties. The findings show that Qt objects lack Windows message handlers and all
objects register their class names with the same parent object name instead of their own
class name. The project describes two different solutions for the problem. The first
solution is very strait, Qt kernel has been modified and message handlers have been
added. In the second solution, Qt object windows have been sub classed and inter process
communication has been used. These two solutions have been evaluated.
Keywords
Automated testing tools, C++, inter process communication, Qt, Rational Robot, test
automation, Windows messages, window sub classing.
i
Acknowledgements
My sincere and hearty gratitude needs to be expressed to a number of people who made
this thesis possible. I am deeply grateful to my supervisor Magnus Werner for his support
and patience, and for his kindness and his great enthusiasm for the project, which have
made it a tremendous pleasure and inspiration to work with him. Per Burman was also of
great assistance in the preparatory phase of this thesis. Thanks also go to all these people
and many others I met at Saab Training Systems AB, who helped in small but important
ways.
I would also like to thank my examiner, Henrik Eriksson, for all the suggestions,
feedback and guidance I have received throughout the project.
Out with the work setting, I would also like to offer my fondest regards to my parents,
sister and friends for their support and encouragement.
iii
Contents
v
Chapter 1
Introduction
1.1 Background
Testing is an important activity in the software development process, aiming at
uncovering and correcting errors in the software. Since this activity is time-consuming
and resource-intensive, parts of the testing process are automated. Automated software
testing helps improve testers’ productivity. It increases test coverage levels, speeds up
test turnaround time and cuts costs of testing. To automate the test IBM Rational Robot is
widely used. With Rational Robot any one can create, modify, and execute automated
functional, distributed functional, regression and smoke tests for software applications
that are built using a wide variety of integrated development environments (IDEs) and
languages. Unfortunately it does not support Qt, the multi-platform C++ GUI toolkit. Qt
is a multiplatform, C++ application framework that lets developers write one application
that will run natively on Windows, Linux/Unix, Mac OS X, and embedded Linux with a
simple recompile. It is elegant, intuitive, completely object oriented.
Saab Training Systems AB is using Qt to build ExPERT, the software for planning &
preparation, data initializations, exercise execution and analysis & evaluation of military
training. So, they felt for a communication interface between Qt and Rational Robot to
test ExPERT automatically.
1.2 Goal
The goal of this project was to design and implement an interface between Qt and
Rational Robot. With this interface Rational Robot should perform the following actions:
• Record scripts of Qt applications
• Run previously recorded scripts
• Read the various properties of the Qt objects
• Insert verification points of any type.
1
1.3 Limitations
SAAB Training Systems is very much interested to test ExPERT with Rational Robot.
The original implementation only handles the Qt objects that are used in the ExPERT.
Due to the limited resources, it does not include the design and implementation of the full
communication interface between Qt toolkit objects and Rational Robot.
2
Chapter 2
Theoretical Background
2.1 Introduction
The purpose of this chapter is to give the reader an opportunity to acquire the knowledge
needed to fully understand the thesis work. The windows programming fundamentals,
window classes and messages will be discussed here.
2.2 Windows Programming
Unlike MS-DOS-based applications, Windows-based applications are event-driven. They
do not make explicit function calls (such as C run-time library calls) to obtain input.
Instead, they wait for the system to pass input to them. The system passes all input for an
application to the various windows in the application. Each window has a function, called
a window procedure that the system calls whenever it has input for the window. The
window procedure processes the input and returns control to the system.
2.3 Windows Messages
The system passes input to a window procedure in the form of messages. Messages are
generated by both the system and applications. The system generates a message at each
input event for example, when the user types, moves the mouse, or clicks a control such
as a scroll bar. The system also generates messages in response to changes in the system
brought about by an application, such as when an application changes the pool of system
font resources or resizes one of its windows. An application can generate messages to
direct its own windows to perform tasks or to communicate with windows in other
applications [3].
The system sends a message to a window procedure with a set of four parameters: a
window handle, a message identifier, and two values called message parameters. The
window handle identifies the window for which the message is intended. The system uses
it to determine which window procedure should receive the message.
3
WM_PAINT
WM_KEYDOWN
WM_COMMAN
D
WM_LBUTTON
WM_SIZE
DOWN
Message
Queue
(Retrieved Message)
Application
WinMain()
Message
Loop
Window Procedure
(Dispatched Message)
Message Handler
Message Handler
Message Handler
Message Handler
Message Handler
Message Handler
(Unprocessed Messages)
DefWindowProc
Figure 2.1 Message handling of a win32 application
A message identifier is a named constant that identifies the purpose of a message. When a
window procedure receives a message, it uses a message identifier to determine how to
process the message. For example, the message identifier WM_PAINT tells the window
procedure that the window's client area has changed and must be repainted.
Message parameters specify data or the location of data used by a window procedure
when processing a message. The meaning and value of the message parameters depend
4
on the message. A message parameter can contain an integer, packed bit flags, a pointer
to a structure containing additional data, and so on. When a message does not use
message parameters, they are typically set to NULL. A window procedure must check the
message identifier to determine how to interpret the message parameters.
Figure 2.1 shows how messages are handled by the application.
2.4 Message Types
This section describes the two types of messages:
• System-Defined Messages
• Application-Defined Messages
2.4.1 System-Defined Messages
The system sends or posts a system-defined message when it communicates with an
application. It uses these messages to control the operations of applications and to
provide input and other information for applications to process. An application can also
send or post system-defined messages. Applications generally use these messages to
control the operation of control windows created by using pre-registered window classes.
Prefix
BM
CB
DTM
EM
HDM
HKM
IPM
LB
LVM
SB
SBM
STM
TB
TCM
TVM
WM
Message category
Button control
Combo box control
Date and time picker control
Edit control
Header control
Hot key control
IP adress control
List box control
List view control
Status bar window
Scroll bar control
Static control
Toolbar
Tab control
Tree-view control
General window
Table 2.1 prefixes and their related message categories
5
Each system-defined message has a unique message identifier and a corresponding
symbolic constant (defined in the software development kit (SDK) header files) that
states the purpose of the message. For example, the WM_PAINT constant requests that a
window paint its contents.
Symbolic constants specify the category to which system-defined messages belong. The
prefix of the constant identifies the type of window that can interpret and process the
message. Table 2.1 contains the example prefixes and their related message categories.
General window messages cover a wide range of information and requests, including
messages for mouse and keyboard input, menu and dialog box input, window creation
and management, and Dynamic Data Exchange (DDE).
2.4.2 Application-Defined Messages
An application can create messages to be used by its own windows or to communicate
with windows in other processes. If an application creates its own messages, the window
procedure that receives them must interpret the messages and provide appropriate
processing.
2.5 Message Routing
The system uses two methods to route messages to a window procedure: posting
messages to a first-in, first-out queue called a message queue, a system-defined memory
object that temporarily stores messages, and sending messages directly to a window
procedure.
Messages posted to a message queue are called queued messages. They are primarily the
result of user input entered through the mouse or keyboard, such as
WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, and WM_CHAR
messages. Other queued messages include the timer, paint, and quit messages:
WM_TIMER, WM_PAINT, and WM_QUIT. Most other messages, which are sent
directly to a window procedure, are called nonqueued messages.
2.5.1 Queued Messages
The system can display any number of windows at a time. To route mouse and keyboard
input to the appropriate window, the system uses message queues. The system maintains
a single system message queue and one thread-specific message queue for each graphical
user interface (GUI) thread. To avoid the overhead of creating a message queue for
nonGUI threads, all threads are created initially without a message queue. The system
creates a thread-specific message queue only when the thread makes its first call to one of
the User or Windows Graphics Device Interface (GDI) functions.
Whenever the user moves the mouse, clicks the mouse buttons, or types on the keyboard,
the device driver for the mouse or keyboard converts the input into messages and places
6
them in the system message queue. The system removes the messages, one at a time,
from the system message queue, examines them to determine the destination window,
and then posts them to the message queue of the thread that created the destination
window. A thread's message queue receives all mouse and keyboard messages for the
windows created by the thread. The thread removes messages from its queue and directs
the system to send them to the appropriate window procedure for processing.
With the exception of the WM_PAINT message, the system always posts messages at
the end of a message queue. This ensures that a window receives its input messages in the
proper first in, first out (FIFO) sequence. The WM_PAINT message, however, is kept in
the queue and is forwarded to the window procedure only when the queue contains no
other messages. Multiple WM_PAINT messages for the same window are combined into
a single WM_PAINT message, consolidating all invalid parts of the client area into a
single area. Combining WM_PAINT messages reduces the number of times a window
must redraw the contents of its client area.
The system posts a message to a thread's message queue by filling an MSG structure and
then copying it to the message queue. Information in MSG includes: the handle of the
window for which the message is intended, the message identifier, the two message
parameters, the time the message was posted, and the mouse cursor position. A thread
can post a message to its own message queue or to the queue of another thread by using
the PostMessage or PostThreadMessage function.
An application can remove a message from its queue by using the GetMessage function.
To examine a message without removing it from its queue, an application can use the
PeekMessage function. This function fills MSG with information about the message.
After removing a message from its queue, an application can use the DispatchMessage
function to direct the system to send the message to a window procedure for processing.
DispatchMessage takes a pointer to MSG that was filled by a previous call to the
GetMessage or PeekMessage function. DispatchMessage passes the window handle,
the message identifier, and the two message parameters to the window procedure.
2.5.2 Nonqueued Messages
Nonqueued messages are sent immediately to the destination window procedure,
bypassing the system message queue and thread message queue. The system typically
sends nonqueued messages to notify a window of events that affect it. For example, when
the user activates a new application window, the system sends the window a series of
messages, including WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR.
These messages notify the window that it has been activated, that keyboard input is being
directed to the window, and that the mouse cursor has been moved within the borders of
the window.
7
2.6 Message Handling
An application must remove and process messages posted to the message queues of its
threads. A single-threaded application usually uses a message loop in its WinMain
function to remove and send messages to the appropriate window procedures for
processing. Applications with multiple threads can include a message loop in each thread
that creates a window.
2.6.1 Message Loop
A simple message loop consists of one function call to each of these three functions:
GetMessage, TranslateMessage, and DispatchMessage. Note that if there is an error,
GetMessage returns -1 -- thus the need for the special testing.
The GetMessage function retrieves a message from the queue and copies it to a structure
of type MSG. It returns a nonzero value, unless it encounters the WM_QUIT message,
in which case it returns FALSE and ends the loop. In a single-threaded application,
ending the message loop is often the first step in closing the application. An application
can end its own loop by using the PostQuitMessage function, typically in response to the
WM_DESTROY message in the window procedure of the application's main window.
A thread's message loop must include TranslateMessage if the thread is to receive
character input from the keyboard. The system generates virtual-key messages
(WM_KEYDOWN and WM_KEYUP) each time the user presses a key. A virtual-key
message contains a virtual-key code that identifies which key was pressed, but not its
character value. To retrieve this value, the message loop must contain
TranslateMessage, which translates the virtual-key message into a character message
(WM_CHAR) and places it back into the application message queue. The character
message can then be removed upon a subsequent iteration of the message loop and
dispatched to a window procedure.
The DispatchMessage function sends a message to the window procedure associated
with the window handle specified in the MSG structure. If the window handle is
HWND_TOPMOST, DispatchMessage sends the message to the window procedures of
all top-level windows in the system. If the window handle is NULL, DispatchMessage
does nothing with the message.
An application's main thread starts its message loop after initializing the application and
creating at least one window. Once started, the message loop continues to retrieve
messages from the thread's message queue and to dispatch them to the appropriate
windows. The message loop ends when the GetMessage function removes the
WM_QUIT message from the message queue.
Only one message loop is needed for a message queue, even if an application contains
many windows. DispatchMessage always dispatches the message to the proper window;
8
this is because each message in the queue is an MSG structure that contains the handle of
the window to which the message belongs.
2.7 Message Filtering
An application can choose specific messages to retrieve from the message queue (while
ignoring other messages) by using the GetMessage or PeekMessage function to specify a
message filter. The filter is a range of message identifiers (specified by a first and last
identifier), a window handle, or both. GetMessage and PeekMessage use a message filter
to select which messages to retrieve from the queue. Message filtering is useful if an
application must search the message queue for messages that have arrived later in the
queue. It is also useful if an application must process input (hardware) messages before
processing posted messages.
2.8 Posting and Sending Messages
Any application can post and send messages. Like the system, an application posts a
message by copying it to a message queue and sends a message by passing the message
data as arguments to a window procedure. To post messages, an application uses the
PostMessage function. An application can send a message by calling the SendMessage,
BroadcastSystemMessage, SendNotifyMessage etc. functions.
2.8.1 Posting Messages
An application typically posts a message to notify a specific window to perform a task.
PostMessage creates an MSG structure for the message and copies the message to the
message queue. The application's message loop eventually retrieves the message and
dispatches it to the appropriate window procedure.
An application can post a message without specifying a window. If the application
supplies a NULL window handle when calling PostMessage, the message is posted to the
queue associated with the current thread. Because no window handle is specified, the
application must process the message in the message loop. This is one way to create a
message that applies to the entire application, instead of to a specific window.
Occasionally, you may want to post a message to all top-level windows in the system. An
application can post a message to all top-level windows by calling PostMessage and
specifying HWND_TOPMOST in the hwnd parameter.
2.8.2 Sending Messages
An application typically sends a message to notify a window procedure to perform a task
immediately. The SendMessage function sends the message to the window procedure
corresponding to the given window. The function waits until the window procedure
9
completes processing and then returns the message result. Parent and child windows
often communicate by sending messages to each other. For example, a parent window
that has an edit control as its child window can set the text of the control by sending a
message to it. The control can notify the parent window of changes to the text that are
carried out by the user by sending messages back to the parent.
2.9 Window Classes
Each window class has an associated window procedure shared by all windows of the
same class. The window procedure processes messages for all windows of that class and
therefore controls their behavior and appearance. A process must register a window class
before it can create a window of that class. Registering a window class associates a
window procedure, class styles, and other class attributes with a class name. When a
process specifies a class name in the CreateWindow or CreateWindowEx function, the
system creates a window with the window procedure, styles, and other attributes
associated with that class name.
This section discusses the following topics.
• Types of Window Classes
• How the System Locates a Window Class
• Registering a Window Class
• Elements of a Window Class
2.9.1 Types of Window Classes
There are three types of window classes [3]:
• System Classes
• Application Global Classes
• Application Local Classes
These types differ in scope and in when and how they are registered and destroyed.
System Classes
A system class is a window class registered by the system. Many system classes are
available for all processes to use, while others are used only internally by the system.
Because the system registers these classes, a process cannot destroy them.
Table 2.2 describes the system classes that are available for use by all processes [5].
10
Class
Button
ComboBox
Edit
ListBox
ScrollBar
Static
Description
The class for a button.
The class for a combo box.
The class for an edit control.
The class for a list box.
The class for a scroll bar.
The class for a static control.
Table 2.2 System windows classes
Table 2.3 describes the system classes that are available only for use by the system [5].
They are listed here for completeness sake.
Class
#32768
#32769
#32770
#32771
Description
The class for a menu.
The class for the desktop window.
The class for a dialog box.
The class for the task switch window.
Table 2.3 Kernel window classes
Application Global Classes
An application global class is a window class registered by an executable or dynamic-link
library (DLL) that is available to all other modules in the process. For example, a .dll can
call the RegisterClass function to register a window class that defines a custom control as
an application global class so that a process that loads the .dll can create instances of the
custom control [3].
To remove an application global class and free the storage associated with it, use the
UnregisterClass function.
Application Local Classes
An application local class is any window class that an executable or .dll registers for its
exclusive use. Although you can register any number of local classes, it is typical to
register only one. This window class supports the window procedure of the application's
main window.
11
The system destroys a local class when the module that registered it closes. An
application can also use the UnregisterClass function to remove a local class and free the
storage associated with it.
2.9.2 How the System Locates a Window Class
The system maintains a list of structures for each of the three types of window classes.
When an application calls the CreateWindow or CreateWindowEx function to create a
window with a specified class, the system uses the following procedure to locate the
class.
1. Search the list of application local classes for a class with the specified name
whose instance handle matches the module's instance handle. (Several modules
can use the same name to register local classes in the same process.)
2. If the name is not in the application local class list, search the list of application
global classes.
3. If the name is not in the application global class list, search the list of system
classes.
All windows created by the application use this procedure, including windows created by
the system on the application's behalf, such as dialog boxes. It is possible to override
system classes without affecting other applications. That is, an application can register an
application local class having the same name as a system class. This replaces the system
class in the context of the application but does not prevent other applications from using
the system class.
2.9.3 Registering a Window Class
A window class defines the attributes of a window, such as its style, icon, cursor, menu,
and window procedure. The first step in registering a window class is to fill in a
WNDCLASSEX structure with the window class information. Next, pass the structure to
the RegisterClassEx function.
If you register the window class using the ANSI version of RegisterClassEx,
RegisterClassExA, the application requests that the system pass text parameters of
messages to the windows of the created class using the ANSI character set; if you register
the class using the Unicode version of RegisterClassEx, RegisterClassExW, the
application requests that the system pass text parameters of messages to the windows of
the created class using the Unicode character set. The IsWindowUnicode function
enables applications to query the nature of each window.
The executable or DLL that registered the class is the owner of the class. The system
determines class ownership from the hInstance member of the WNDCLASSEX
structure passed to the RegisterClassEx function when the class is registered. For DLLs,
the hInstance member must be the handle to the .dll instance.
12
In Windows 95/Windows 98/Windows Me, the class is destroyed when the owner closes
or is unloaded. For this reason, the process must destroy all windows using the class
before the owner closes or is unloaded. But in Windows NT, Windows 2000 and
Windows XP, the class is not destroyed when the .dll that owns it is unloaded. Therefore,
if the system calls the window procedure for a window of that class, it will cause an
access violation, because the .dll containing the window procedure is no longer in
memory. The process must destroy all windows using the class before the .dll is unloaded
and call the UnregisterClass function.
2.9.4 Elements of a Window Class
The elements of a window class define the default behavior of windows belonging to the
class. The application that registers a window class assigns elements to the class by
Element
Class Name
Window
Procedure
Address
Instance Handle
Class Cursor
Class Icons
Class
Background
Brush
Class Menu
Purpose
Distinguishes the class from other registered classes.
Pointer to the function that processes all messages sent to windows in
the class and defines the behavior of the window.
Identifies the application or .dll that registered the class.
Defines the mouse cursor that the system displays for a window of the
class.
Defines the large icon and the small icon (Windows 95/98/Me, Windows
NT 4.0 and later).
Defines the color and pattern that fill the client area when the window is
opened or painted.
Specifies the default menu for windows that do not explicitly define a
menu.
Class Styles
Defines how to update the window after moving or resizing it, how to
process double-clicks of the mouse, how to allocate space for the device
context, and other aspects of the window.
Extra Class
Specifies the amount of extra memory, in bytes, that the system should
Memory
reserve for the class. All windows in the class share the extra memory
and can use it for any application-defined purpose. The system initializes
this memory to zero.
Extra Window Specifies the amount of extra memory, in bytes, that the system should
Memory
reserve for each window belonging to the class. The extra memory can
be used for any application-defined purpose. The system initializes this
memory to zero.
Table 2.4 window class elements
13
setting appropriate members in a WNDCLASSEX structure and passing the structure to
the RegisterClassEx function. The window class elements are as shown in table 2.4.
Although a complete window class consists of many elements, the system requires only
that an application supply a class name, the window-procedure address, and an instance
handle. Use the other elements to define default attributes for windows of the class, such
as the shape of the cursor and the content of the menu for the window. One must initialize
any unused members of the WNDCLASSEX structure to zero or NULL.
Class Name
Every window class needs a Class Name to distinguish one class from another. Assign a
class name by setting the lpszClassName member of the WNDCLASSEX structure to
the address of a null-terminated string that specifies the name. Because window classes
are process specific, window class names need to be unique only within the same process.
Also, because class names occupy space in the system's private atom table, one should
keep class name strings as short a possible. The GetClassName function retrieves the
name of the class to which a given window belongs.
Window Procedure Address
Every class needs a window-procedure address to define the entry point of the window
procedure used to process all messages for windows in the class. The system passes
messages to the procedure when it requires the window to carry out tasks, such as
painting its client area or responding to input from the user. A process assigns a window
procedure to a class by copying its address to the lpfnWndProc member of the
WNDCLASSEX structure.
Instance Handle
Every window class requires an instance handle to identify the application or .dll that
registered the class. The system requires instance handles to keep track of all of modules.
The system assigns a handle to each copy of a running executable or .dll.
The system passes an instance handle to the entry-point function of each executable
and .dll. The executable or .dll assigns this instance handle to the class by copying it to
the hInstance member of the WNDCLASSEX structure.
In Windows 95/Windows 98/Windows Me, multiple instances of the same application
or .dll use the same code segment, but each has its own data segment. The system uses an
instance handle to identify the data segment that corresponds to a particular instance of an
application or .dll.
14
2.10 About Window Procedures
Each window is a member of a particular window class. The window class determines the
default window procedure that an individual window uses to process its messages. All
windows belonging to the same class use the same default window procedure. For
example, the system defines a window procedure for the combo box class
(COMBOBOX); all combo boxes then use that window procedure [5].
An application typically registers at least one new window class and its associated
window procedure. After registering a class, the application can create many windows of
that class, all of which use the same window procedure. Because this means several
sources could simultaneously call the same piece of code.
2.10.1 Structure of a Window Procedure
A window procedure is a function that has four parameters and returns a signed value.
The parameters consist of a window handle, a UINT message identifier, and two message
parameters declared with the WPARAM and LPARAM data types. Message parameters
often contain information in both their low-order and high-order words. The
interpretation of the return value depends on the particular message. Because it is
possible to call a window procedure recursively, it is important to minimize the number
of local variables that it uses. When processing individual messages, an application
should call functions outside the window procedure to avoid excessive use of local
variables, possibly causing the stack to overflow during deep recursion.
2.10.2 Default Window Procedure
The default window procedure function, DefWindowProc defines certain fundamental
behavior shared by all windows. The default window procedure provides the minimal
functionality for a window. An application-defined window procedure should pass any
messages that it does not process to the DefWindowProc function for default processing.
2.11 Subclassing Window
Subclassing is a technique that allows an application to intercept messages destined for
another window [6]. An application can augment, monitor, or modify the default
behavior of a window by intercepting messages meant for another window. Subclassing
is an effective way to change or extend the behavior of a window without redeveloping
the window. When a window is created, the 32-bit versions of the Microsoft Windows™
operating system take the address of the window procedure in the WNDCLASS structure
and copy it to the new window's information structure. When a message is sent to the
window, Windows calls the window procedure through the address in the window's
information structure. To subclass a window, you substitute a new window procedure that
15
receives all the messages meant for the original window by substituting the window
procedure address with the new window procedure address.
2.11.1 Types of Subclassing
The two types of subclassing are instance subclassing and global subclassing.
Instance subclassing is subclassing an individual window's information structure. With
instance subclassing, only the messages of a particular window instance are sent to the
new window procedure.
Global subclassing is replacing the address of the window procedure in the
WNDCLASS structure of a window class. All subsequent windows created with this
class have the substituted window procedure's address. Global subclassing affects only
windows created after the subclass has occurred. At the time of the subclass, if any
windows of the window class that is being globally subclassed exist, the existing
windows are not affected by the global subclass. If the application needs to affect the
behavior of the existing windows, the application must subclass each existing instance of
the window class.
2.12 Qt for windows
Qt is a C++ toolkit for multiplatform GUI and application development. In addition to the
C++ class library, Qt includes tools to make writing applications fast and straightforward.
Qt's multiplatform capabilities and internationalization support ensure that Qt
applications reach the widest possible market.
Qt/Windows uses the Win32 API and GDI for events and drawing primitives. Qt does not
use MFC or any other toolkit. In particular, Qt does not use the inflexible "common
controls", but rather provides its own more powerful, customizable widgets [9]. Qt
provides a full set of widgets. Widgets are visual elements that are combined to create
user interfaces. Buttons, menus, scroll bars, message boxes, and application windows are
all examples of widgets. Qt's widgets are not arbitrarily divided between "controls" and
"containers"; all widgets can be used both as controls and as containers. Custom widgets
can easily be created by sub-classing existing Qt widgets, or created from scratch on the
rare occasion when this is necessary.
Widgets are instances of QWidget or one of its subclasses.
16
Figure 2.2 An extract from the QWidget class hierarchy
Qt/Windows creates a window when a widget is created and the class name of this
window is ‘QWidget’. This class has an associated window procedure shared by all
windows of the ‘QWidget’ class. Thus, in Qt, all visual controls share the same class
name as well as the same window procedure.
2.12 Rational Robot
Award-winning IBM® Rational® Robot V2003 automates functional testing of graphical
user interfaces. With Rational Robot user can create, modify, and execute automated
functional, distributed functional, regression and smoke tests for software applications
that are built using a wide variety of integrated development environments (IDEs) and
languages [10].
Ease New Testers into Automation
IBM Rational Robot is the best-of-breed functional testing tool that facilitates success
even before testers have learned advanced scripting skills. And it ships with the tester’s
desktop, IBM Rational Test Manager, from which testers plan, organize, execute, manage
and report on all testing activities, including reporting on manual testing. This dual testand-manage capability is the ideal starting point for automating testing.
Give Advanced Testers a Powerful Tool
IBM Rational Robot is an extensible, flexible functional testing tool that experienced
testers can use to modify test scripts and improve the depth of their testing.
With Rational Robot V2003 you can:
• Automate regression and configuration testing
• Extend test scripts with conditional logic and call any DLL or Windows API function
IBM Rational Robot captures all HTML and DHTML properties, including link targets
and non-visible data.
17
Rational Robot provides test cases for objects such as menus, lists, alphanumeric
characters, and bitmaps, and allows you to create user-defined test cases that call external
DLLs or executables. It offers specialized test cases for environment-specific objects
such as Java controls, PowerBuilder DataWindows, ActiveX Controls, Special Oracle
Forms objects, OCXs, Visual Basic objects, and VBXs.
Quick and Easy Visual Analysis
IBM Rational Robot automatically logs all test results, color-coding them in the test log
viewer for fast visual analysis. By double-clicking on an entry, Rational Robot brings you
directly to the corresponding line in the test script for fast analysis.
Multiple IDE and Language Support
Rational Robot supports the following IDE and languages
Java Environments
Microsoft Visual Studio.NET
HTML, XML and DHTML Applications
Oracle Developer/2000
Visual Basic Applications
PowerBuilder Applications
Unfortunately, it does not support Qt.
18
Chapter 3
Analysis
3.1 Introduction
This chapter describes the results of the analysis on why Rational Robot cannot
communicate with Qt widgets.
As it has been mentioned earlier, there is no proper documentation about how Rational
Robot interacts with objects, some sample applications have been created with Visual C+
+ & Visual Basic, the languages that are supported by robot. Applying Rational Robot on
those two environments’ applications some conclusions have been drawn.
3.2 How Rational Robot Interacts with object
While recording scripts, when the user clicks on an object, Rational Robot gets the object
type by getting the class name of the window associated with the object. There is a
window API called GetClassName to retrieve the class name of the window. Robot
internally maintains a list of mapping between the window class name and the object
type. From that list it gets the object type. Then it sends messages corresponding to that
object type to retrieve more information about where the user has clicked on an object.
For Example, when a user clicks on an item of a listbox, the following actions occur,
Rational Robot retrieves the handle of the window associated with the list box by calling
windows API WindowFromPoint. Then it calls the GetClassName API to retrieve the
class name of the window. For a VC++ app it finds the class name as ‘ListBox’ and for a
VB App it finds ‘ThunderListBox’. For the both class names Rational Robot sees the
object as a listbox since it maintains an object-type mapping for known class names.
Figure 3.1 shows the interaction between Rational Robot and AUT.
19
GetClassName()
Rational
Robot
ListBox
Send WindowMessages
related to ListBox
Get the corrosponding
result
Figure 3.1 Interaction between Rational Robot and win32 application
After determining the object type as listbox Rational Robot sends messages related to
listbox. First of all it sends LB_GETCOUNT message to the window associated with the
listbox. As VB or VC++ is a standard Windows programming environment, all message
handlers for all controls are fully implemented. So when the listbox control gets the
LB_GETCOUNT message it returns total number of items in the listbox.
Robot sends the LB_GETCURSEL to the listbox; it returns the index of the currently
selected item which one is selected due to the mouse click. Robot sends
LB_GETTEXTLEN to listbox; it returns the length of the selected item. Finally robot
sends LB_GETTEXT to retrieve the text of the currently selected item. Thus Rational
Robot gets the attributes of an object.
3.3 Why Rational Robot cannot recognize Qt objects?
“During recording, Robot recognizes all the standard Windows GUI objects that you
click, such as check boxes and list boxes. Each of these objects is associated with one of
a fixed list of object types. The association of an object with an object type is generally
based on the class name of the window associated with the object.” [11]
In Qt all GUI Objects ( e.g. ListBox, Button etc) are derived from QWidget, and the class
name of the windows associated with these GUI objects is ‘QWidget’ . That is why
Rational Robot sees all objects (Listbox, Button) etc as same object.
20
3.4 Why Rational Robot cannot read attributes of an object?
“An object might look and act like a standard toolbar but might actually not respond
correctly to the messages that are sent to a standard toolbar” [11]. Rational Robot
retrieves attributes of a window control by sending Windows messages to the window
associated with the object. E.g. To get the number of elements in a Listbox Rational
Robot sends LB_GETCOUNT message to the window associated with the listbox, then a
normal win32 listbox return the number of elements. But Qt Objects does not response
with standard Windows messages, that’s why Rational Robot cannot retrieve the
attributes of an object.
3.5 Observations
From the above analysis it is clear that there are two main obstacles which prevent
communication between Rational Robot and Qt. Firstly, all Qt objects register themselves
as QWidget which prevents them from being identified as different object types. The
other one is absence of message handlers. As Qt objects do not interact with each other
by message passing, there is no implementation of control Windows messages like
LB_GETCOUNT, LB_GETTEXT etc in Qt.
21
Chapter 4
Technical Solutions
4.1 Introduction
An important goal is to achieve a solution that is fast and has as small overhead as
possible. In this chapter the existing Qt toolkit’s work flow is discussed and the proposed
solutions are also designed.
4.2 Existing work flow
The existing work flow is divided into two parts, the object creation operation and the
message handler operation.
4.2.1 Object Creation Operation
In Qt all visual objects are derived from QWidget class. QWidget class has only one
constructor with three parameters parent, name and flags. If parent parameter is 0, the
new widget becomes a top-level window. If parent is another widget, this widget
becomes a child window inside parent. The new widget is deleted when its parent is
deleted. On the Windows platform the name parameter is used in the caption of the
window. The frame parameter is used to customize the window frame of a top-level
widget.
In the QWidget constructor a window is created with ‘QWidget’ class name. This
window is used to receive events for mouse and keyboard input, menu and dialog box
input etc. When other objects that are derived from the QWidget class are created they
always call the constructor of the QWidget class in their constructor. Thus QWidget and
its sub classes always create windows with ‘QWidget’ class name.
The figure 4.1 shows what happens in existing Qt when a ‘QLineEdit’ or QLabel object
is created.
23
QWidget(…) {
Register Class ”QWidget”
Create a window ’QWidget’ Type
Do other initialization
}
QFrame(…):QWidget(…) {
Do initialization
………….
}
QLineEdit(…):QFrame(…) {
Do initialization
………….
}
QLabel(…):QFrame (…) {
Do initialization
………….
}
Figure 4.1 Object creation in existing Qt
In the figure 4.1 it is clear that when any object is created a ‘QWidget’ type window is
created. So, in Qt every visual object’s window is ‘QWidget’ type.
4.2.2 Message Handling Operation
In existing Qt, as every visual object is of ‘QWidget’ type, every Windows message is
handled in a single WndProc. In Qt’s WndProc only the messages with prefix WM_ are
QtWndProc (msg,…..)
{
switch(msg) {
case WM_LBUTTONDOWN :
……..
break;
case WM_....... // General window messages
………….
break;
}
Return DefWindowProc(…)
}
Figure 4.2 Windows message handlers in existing Qt
24
handled. The messages with WM_ prefix are general window messages that cover a wide
range of information and requests, including messages for mouse and keyboard input,
menu and dialog box input, window creation and management. But in Qt’s WndProc
there is no message handler for controls (Listbox, Combobox,..) that Rational Robot can
interact with.
4.3 Proposed operation flow
The aim of this design is to add functionality to Qt, so it registers different Control
objects using the corresponding class names allowing Rational Robot to send the
corresponding messages to the controls.
4.3.1 Object Creation Operation
To give all controls different names, an extra constructor has been added to the QWidget
Class as well as to its intermediate subclasses. In this constructor an extra parameter,
ClassName, has been added. When a control is created it passes its class name as
parameter to its super class. In the QWidget constructor, this ClassName parameter is
used to register a new class if a class with the same name has not yet been created. Thus
every control is registered as its corresponding class name. Now Rational Robot would
recognize different controls as different types.
QWidget(ClassName,…) {
Register Class ClassName
Create a window ClassName Type
Do other initialization
}
QFrame(ClassName,…):
QWidget(ClassName ,…) {
Do initialization
………….
}
QLineEdit(…):
QFrame(“QLineEdit”, …) {
Do initialization
………….
}
QLabel(…):
QFrame (“QLabel”,…) {
Do initialization
………….
}
Figure 4.3 Object creation in proposed Qt
25
In figure 4.3 it is clear that when the QLineEdit widget is created, a parameter with
“QLineEdit” is sent to its parent QFrame. QFrame sends it to QWidget, then QWidget
register a class with QLineEdit and a window is created using this class. Other control
widgets register their class name in the same manner.
4.3.2 Message Handling Operation
The messages that are sent by the Rational Robot to communicate with the application
have been identified. Message handlers should be added for those messages in the Qt’s
WndProc. In figure 4.4 skeleton of the proposed QtWndProc has been shown. There is
only one window procedure in the whole Qt toolkit. So, this QtWndProc is called for
each and every message generated from any of the Qt control. The message handlers
should be added very carefully, as this procedure is called very frequently.
QtWndProc(msg,…..)
{
switch(msg) {
case WM_LBUTTONDOWN :
……..
break;
case WM_....... // General window messages
………….
break;
case LB_..... // all messages related to Listbox
……
break
………….All messages for TabBar, Listview,
ComboBox etc. has been added.
}
}
Return DefWindowProc(…)
Figure 4.4 Windows message handlers in proposed Qt
4.4 Alternative Solution
In the previous solution Qt’s source has been changed. So it is necessary to do the whole
work again when a new release of Qt arrives. An alternative solution alleviates the need
to modify the Qt source.
26
It is possible to get the class name of a Qt object during runtime, because QWidget class
has a member function called className which returns the object’s original class name.
But Rational Robot uses only Windows API GetClassName to get the class name. So, by
hooking the windows API GetClassName, the object’s original class name can be
supplied to the Rational Robot.
For Message handling issue, by sub classing ‘QWidget’ class, all the missing message
handlers can be added to the sub classed window procedure.
Hook GetClassName API,
Return control’s classname
instead of ‘QWidget’.
GetClassName()
Rational
Robot
”QListBox”
Solve
classname
Subclassed QWidget’s
WndProc
Added all missing
message handlers
Message has been processes in
subclassed WndProc
Send WindowMessages
related to ListBox
Get the corresponding
result
Figure 4.5 Interactions between Rational Robot and Qt Application in proposed system
In figure 4.5 a proposed work flow has been shown for a list box control. If a user clicks
on an item in the list box, Rational Robot calls GetClassName API. The hooked function
will be called. In the hooked function the original class name QListBox will be retrieved
and returned to the Rational Robot. Then Rational Robot sends messages related to
listbox. As the list box is sub classed and all the message handlers are added, it responds
with the expected messages. Thus Rational Robot can interact with the application
properly.
27
28
Chapter 5
Implementation
5.1 Introduction
In order to implement the design of the previous chapter, the kernel of Qt has been
modified. The procedure turned out to be very time consuming since almost all of the
internal execution flow of the Qt had to be understood. Reliable functionality is essential,
since changes are made in the kernel of Qt, it could go terribly wrong if the added code
does not work properly.
5.2 Software Tools
To implement the design following tools have been used.
5.2.1 Visual Studio 6
The Visual Studio 6.0 family of development products includes many development
environments. Among those environments Visual C++ and Visual Basic have been used.
Visual C++ is a very powerful IDE for developing C/C++ applications, services, and
controls for Win32 platforms, including Windows 95/98 and Windows NT/2000. As Qt
does not have its own IDE, for adding, modifying and compiling the source code of Qt
Visual C++ is used.
Visual Basic provides a complete set of tools to simplify rapid application development
including ActiveX™ technologies, Data access features etc. Visual Basic is used to create
some sample applications, consisting ActiveX component written in Qt during the
implementation process.
5.2.2 Qt Designer
Qt Designer is a full-fledged GUI builder. Qt Designer makes it easy to experiment with
user interface design. The GUI of ExPERT has been developed in Qt Designer. As
ExPERT is a very large application and needs a couple of hours to compile, sample
applications were created using Qt Designer to observe the effects of changing the source
code of Qt during implementation process.
29
5.2.3 Microsoft SPY++
Microsoft Spy++ is a Win32-based utility that gives a graphical view of the system’s
processes, threads, windows, and window messages. As Rational Robot does not come
with technical documentation, SPY++ has been used to find out what window messages
are sent by Rational Robot during interaction with the application under test.
5.3 Coding and Testing
5.3.1 Modifying the Qt kernel
The goal of this project is to enable ExPERT with Rational Robot. The Qt objects that are
used in ExPERT have been identified. A test application has been written with all of
those objects using Qt Designer. The purpose of the test application is to shorten the
implementation process. As the changes are made in Qt’s kernel, for every change made
a recompilation of the application is needed. Recompilation of ExPERT takes a couple of
hours.
It is clear from the design, no object’s properties or methods have been changed, only a
single parameter has been added to the object’s constructor and some message handlers
have been added. The message handler will not execute, unless it gets the corresponding
message. Normal Qt applications do not get these messages. Only Rational Robot sends
these messages during interaction with the application. So, the added code does not
execute in applications that are written with this modified version of Qt unless the
application is tested using Rational Robot.
The Implementation is done in modular basis. Every Object (QListBox, QListView,
QLineEdit etc.) is considered as a single module. Modules are implemented and tested
one by one. If one works properly then another is implemented.
For example, LB_GETCOUNT message handler has been written as follows:
LB_GETCOUNT is sent to retrieve the total number of elements in the list box. A pointer
of the QListBox can be found from the Application’s list of widgets that Qt internally
maintains for every application. Then QListBox object has the member function count()
which return the total number of items in the listbox [8]. This is return by
LB_GETCOUNT. Similarly other messages have been implemented. Every message
structure is studied and values are return by calling appropriate methods of Qt Classes.
Every Message handlers are written in the Windows main procedure, the number of local
variables have been kept to a minimum. This is because it is possible to call a window
procedure recursively.
30
5.3.2 Alternative solution
An alternative solution has also been implemented. There are two processes hooking the
API GetClassName and sub classing the ‘QWidget’ class.
Based on DelayLoadProfileDLL.CPP, by Matt Pietrek for MSJ February 2000, a dll is
written, which uses the windows CBT hook to load the dll in the all running process
address spaces [7]. Then it hooks the GetClassName API of Rational Robot process and
it hooks the RegisterClassName API of the process of Qt application under test.
RegisterClassName is hooked because when the application is trying to register the class
‘QWidget’, the hooked function is called. In this hooked function, ‘QWidget’ has been
sub classed. Thereafter every window created with ‘QWidget’ class name, gets the new
WndProc in which all the message handlers have been implemented. These message
handlers are actually implemented in the previous solution.
In the Qt application all controls are of the ‘QWidget’ class, but it is possible to get the
original class name (i.e. program defined class name) of the control during runtime. In
the hooked function of GetClassName, the original class name is acquired. As the hook
function is on the Rational Robot address space, it cannot directly get the class name of
the Qt object which is running in a different address space. So, inter process
communication is needed. This inter process communication is done by message passing.
Rational Robot
address space
GetClassName
Hook function
Send Message and
wait until it returns
the index of the
class name.
AUT address space
Qt’s SubClassed
WndProc
QT_GETCLASSNAME
(User Defined Message)
Index of the ClassName
Find the Original
class name and
return the index of
this class name.
Figure 4.5 Retrieving Qt class name of an object in proposed system
As class names are predefined, a list of class names is maintained on the both sides. Only
the index is passed to another application. So, the inter process communication is
minimal. After getting the original class name, the hooked GetClassName function
returns it to Rational Robot.
31
While recording script Rational Robot tries to get the class names of all windows of the
AUT for every single click. So, for a large application it has a significant overhead to
perform inter process communication for retrieving class names of every windows each
time. A list of window handles and corresponding class name index is maintained to
minimize the inter process communication. As class name index is used instead of class
name itself the list consumes a very small amount of memory.
32
Chapter 6
Conclusion
This chapter summarizes the work presented and compares the different solutions. This
chapter also describes the implementation difficulties and possible future works.
6.1 Implementation Results
As two different solutions have been presented, evaluation is necessary to figure out
which one is the best approach. In the first approach, the Qt kernel has been modified and
in the alternative approach a separate dll is written. The following table shows the
relative pros and cons of the two different approaches.
Performance
Memory
Modified Qt
Separate DLL
For application with thousands of
GUI objects, it is significantly
faster than alternative solution.
It needs very small amount of
extra system memory.
For Small amount of GUI
objects
the
performance
almost the same.
Significant amount of system
memory is needed
Effect on other running It has no effect of other running As dll is loaded into the
process
processes.
address space of all of the
running processes. It has
small overhead to other
running processes.
Recompilation
Recompilation of both the Qt and No recompilation is needed.
the application are needed after Only the host dll needs to be
changes have been made.
running before the application
and the Rational Robot are
executed.
New Release of Qt
Have to rewrite the whole code in Only recompilation is needed
the new version of Qt.
Table 6.1 Pros and cons of the two different approaches of the solution.
33
Although the “separate dll” approach has some performance penalties, it is more
desirable from the industrial point of view. This is because there is no need to modify Qt
after a new release of it.
6.2 Implementation Difficulties
The main difficulty was to find out how Rational Robot interacts with other objects. This
was done by capturing and examining carefully the messages that Rational Robot sends
to interact with applications.
Rational Robot only supports standard windows object. But Qt has some special
composite objects such as QTable. Rational Robot has no support for objects like QTable
which has rows and columns. QTable has been implemented as normal List Box.
Rational Robot also cannot recognize popup menu other than system popup menu. A
wrapper class of QPopupMenu has been written which creates a system popup menu
instead of QPopupMenu.
Another major problem was debugging. As the code that has been written only executes
during execution of Rational Robot on the application and the code itself resides in a dll,
it is not possible to trace it. Debug string has been written to a file to understand what is
happening.
Compilation time is another problem. As the code is written in the kernel of the Qt, after
any modification the whole Qt needs to recompile. Compilation of Qt takes a significant
amount of time.
Rational Robot also lacks user documentations. For example, there is no documentation
about how to select an object containing in an ActiveX component for insertion of a
verification point. At long last it has been found that if the Alt key is down during object
selection Rational Robot can select objects containing in an ActiveX.
6.3 Summary
As it is mentioned earlier due to the time limitation the target has been set to implement a
communication interface between the Qt components of ExPERT and Rational Robot.
The objective is fully accomplished. Now, with this communication interface
• Rational Robot can recognize the objects of ExPERT and it can now record test
scripts.
• Rational Robot can run the previously recorded scripts.
34
•
•
Rational Robot can get the attributes of the objects.
Rational Robot can make verification point of any type.
Though this solution only work for the objects that are used in the ExPERT, it can easily
be extended to make it work with the whole Qt toolkit.
6.4 Future Work
In this thesis the design and implementation of the communication interface between a
set of Qt objects and Rational Robot are discussed. Obviously more work should be done
to make it work efficiently with the whole set of Qt toolkit. The possible future work
might be
•
•
•
Implementing rest of the objects of the Qt toolkit.
Finding a way to update the list of window handles when a window of AUT is
destroyed.
Finding a way to feed new objects to the Rational Robot. This is because in Qt it
is possible to make customize widget that might be totally different from any
existing controls.
The ideas and notions introduced in this thesis could be applicable to a wider spectrum of
application domains and not necessarily limited to Rational Robot application. Thus
formalizing the model would help generalizing Qt to work with different testing
applications.
35
Bibliography
[1] Andrei Alexandrescu. Modern C++ Design, Addison-Wesley Pub Co; 1st edition
(February 13, 2001)
[2] Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns,
Addison-Wesley Pub Co, 1st edition (January 15, 1995).
[3] Johnson M. Hart. Win32 System Programming, Addison-Wesley Pub Co; 2nd Book
and CD-ROM edition (September 29, 2000)
[4] Johnson, R. E., Foote, B. (1988). Designing reusable classes. Journal of ObjectOriented Programming,
[5] MSDN Library Visual Studio 6.0, Microsoft Developer Networks, available at:
http://msdn.microsoft.com/
[6] Petzold, Charles. Programming Windows [Fifth Edition], Microsoft Press.
[7] Pietrek, Matt. Under the Hood Microsoft Systems Journal, February 2000 — Vol
15 No 2
[8] Qt Reference Documentation
http://www.trolltech.com/products/qt/whitepaper/qt-whitepaper.html, verified 200312-08
[9] Qt Whitepaper,
http://www.trolltech.com/products/qt/whitepaper/qt-whitepaper.html, verified 200312-08
[10] Rational® Robot Automated Test http://www.wilsonmar.com/1robot.htm verified
2003-12-08
[11] Rational® Robot User Guide, Rational® TestManager v2003.6.0, 2003
37
Appendix A
Terminology
This section describes some of the terms used through out the document.
ActiveX
All component technologies that are built on the Microsoft Component
Object Model (COM).
API
AUT
Application Programming Interface
Application Under Test
DLL
ExPERT
GDI
Dynamic Link Library
The software for planning & preparation, data initializations, exercise
execution and analysis & evaluation of military training.
Graphic Display Interface
GUI
Graphical User Interface
IDE
Integrated Development Environment
Win32
The application programming interface in Windows 95/98, Windows
NT/2000, and Windows CE that enables applications to use the 32-bit
instructions available on 80386 and higher processors.
Window
control
A predefined child window used in conjunction with another
application window to provide a standardized way for users to make
selections, carry out commands, and perform input and output tasks.
Window
handle
A 32-bit value, assigned by windows kernel that uniquely identifies a
window.
39
Appendix B
List of Window Messages
Following table shows the window massages that are handled in the project and their
corresponding widgets.
Widget
Window Message
QListBox
LB_GETCOUNT
LB_GETITEMRECT
LB_GETCURSEL
LB_GETTEXTLEN
LB_GETTEXT
QTabBar
TCM_HITTEST
TCM_GETITEM
TCM_GETITEMRECT
TCM_GETITEMCOUNT
QListView
TVM_HITTEST
TVM_GETITEM
TVM_GETNEXTITEM
TVM_GETITEMRECT
TVM_GETCOUNT
TVM_EXPAND
TVM_ENSUREVISIBLE
41
Widget
Window Message
QComboBox
CB_GETCOUNT
CB_GETCURSEL
CB_GETLBTEXTLEN
CB_GETLBTEXT
QTable
LB_GETCOUNT
LB_GETITEMRECT
LB_GETCURSEL
LB_GETTEXTLEN
LB_GETTEXT
QLineEdit
QDateTimeEditor
QTimeEdit
EM_GETLINECOUNT
WM_GETTEXTLENGTH
WM_GETTEXT
QRadioButton
BM_GETCHECK
QCheckBox
BM_GETCHECK
42
Avdelning, Institution
Division, Department
Datum
Date
2003-12-17
Institutionen för datavetenskap
581 83 LINKÖPING
Språk
Language
Svenska/Swedish
X Engelska/English
Rapporttyp
Report category
Licentiatavhandling
X Examensarbete
C-uppsats
D-uppsats
ISBN
ISRN LITH-IDA-EX--03/078--SE
Serietitel och serienummer
Title of series, numbering
ISSN
Övrig rapport
____
URL för elektronisk version
http://www.ep.liu.se/exjobb/ida/2003/dd-d/078/
Titel
Title
Författare
Author
Communication Interface between Rational Robot and Qt objects
Nasir Uddin Ahmed
Sammanfattning
Abstract
Automated black box, GUI-level regression test tools are popular in the industry. Currently, IBM Rational
Robot being one of the best testing tools supports wide verity of integrated development environments
(IDEs) and languages. Unfortunately it does not support Qt, the multiplatform C++ GUI toolkit. The
excellent documentation, clean interface, and a sensible approach to the object oriented paradigm makes Qt
one of the most popular GUI toolkits in the world.
The project describes why Rational Robot cannot recognize the Qt objects and their properties. The findings
show that Qt objects lack Windows message handlers and all objects register their class names with the same
parent object name instead of their own class name. The project describes two different solutions for the
problem. The first solution is very strait, Qt kernel has been modified and message handlers have been added.
In the second solution, Qt object windows have been sub classed and inter process communication has been
used. These two solutions have been evaluated.
Nyckelord
Keyword
Automated testing tools, C++, inter process communication, Qt, Rational Robot, test automation, Windows
messages, window sub classing.
[...]... ‘ListBox’ and for a VB App it finds ‘ThunderListBox’ For the both class names Rational Robot sees the object as a listbox since it maintains an object-type mapping for known class names Figure 3.1 shows the interaction between Rational Robot and AUT 19 GetClassName() Rational Robot ListBox Send WindowMessages related to ListBox Get the corrosponding result Figure 3.1 Interaction between Rational Robot and. .. normal win32 listbox return the number of elements But Qt Objects does not response with standard Windows messages, that’s why Rational Robot cannot retrieve the attributes of an object 3.5 Observations From the above analysis it is clear that there are two main obstacles which prevent communication between Rational Robot and Qt Firstly, all Qt objects register themselves as QWidget which prevents them... mouse click Robot sends LB_GETTEXTLEN to listbox; it returns the length of the selected item Finally robot sends LB_GETTEXT to retrieve the text of the currently selected item Thus Rational Robot gets the attributes of an object 3.3 Why Rational Robot cannot recognize Qt objects? “During recording, Robot recognizes all the standard Windows GUI objects that you click, such as check boxes and list boxes... 2.12 Qt for windows Qt is a C++ toolkit for multiplatform GUI and application development In addition to the C++ class library, Qt includes tools to make writing applications fast and straightforward Qt' s multiplatform capabilities and internationalization support ensure that Qt applications reach the widest possible market Qt/ Windows uses the Win32 API and GDI for events and drawing primitives Qt does... Special Oracle Forms objects, OCXs, Visual Basic objects, and VBXs Quick and Easy Visual Analysis IBM Rational Robot automatically logs all test results, color-coding them in the test log viewer for fast visual analysis By double-clicking on an entry, Rational Robot brings you directly to the corresponding line in the test script for fast analysis Multiple IDE and Language Support Rational Robot supports... and call any DLL or Windows API function IBM Rational Robot captures all HTML and DHTML properties, including link targets and non-visible data 17 Rational Robot provides test cases for objects such as menus, lists, alphanumeric characters, and bitmaps, and allows you to create user-defined test cases that call external DLLs or executables It offers specialized test cases for environment-specific objects. .. Figure 4.2 Windows message handlers in existing Qt 24 handled The messages with WM_ prefix are general window messages that cover a wide range of information and requests, including messages for mouse and keyboard input, menu and dialog box input, window creation and management But in Qt s WndProc there is no message handler for controls (Listbox, Combobox, ) that Rational Robot can interact with 4.3... item in the list box, Rational Robot calls GetClassName API The hooked function will be called In the hooked function the original class name QListBox will be retrieved and returned to the Rational Robot Then Rational Robot sends messages related to listbox As the list box is sub classed and all the message handlers are added, it responds with the expected messages Thus Rational Robot can interact with... system’s processes, threads, windows, and window messages As Rational Robot does not come with technical documentation, SPY++ has been used to find out what window messages are sent by Rational Robot during interaction with the application under test 5.3 Coding and Testing 5.3.1 Modifying the Qt kernel The goal of this project is to enable ExPERT with Rational Robot The Qt objects that are used in ExPERT... windows of the ‘QWidget’ class Thus, in Qt, all visual controls share the same class name as well as the same window procedure 2.12 Rational Robot Award-winning IBM® Rational Robot V2003 automates functional testing of graphical user interfaces With Rational Robot user can create, modify, and execute automated functional, distributed functional, regression and smoke tests for software applications ... CB_GETCURSEL CB_GETLBTEXTLEN CB_GETLBTEXT QTable LB_GETCOUNT LB_GETITEMRECT LB_GETCURSEL LB_GETTEXTLEN LB_GETTEXT QLineEdit QDateTimeEditor QTimeEdit EM_GETLINECOUNT WM_GETTEXTLENGTH WM_GETTEXT QRadioButton... elektronisk version http://www.ep.liu.se/exjobb /ida/ 2003/dd-d/078/ Titel Title Författare Author Communication Interface between Rational Robot and Qt objects Nasir Uddin Ahmed Sammanfattning Abstract Automated... LB_GETCURSEL LB_GETTEXTLEN LB_GETTEXT QTabBar TCM_HITTEST TCM_GETITEM TCM_GETITEMRECT TCM_GETITEMCOUNT QListView TVM_HITTEST TVM_GETITEM TVM_GETNEXTITEM TVM_GETITEMRECT TVM_GETCOUNT TVM_EXPAND TVM_ENSUREVISIBLE