/****************************************************************************+ −
**+ −
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).+ −
** All rights reserved.+ −
** Contact: Nokia Corporation (qt-info@nokia.com)+ −
**+ −
** This file is part of the documentation of the Qt Toolkit.+ −
**+ −
** $QT_BEGIN_LICENSE:LGPL$+ −
** No Commercial Usage+ −
** This file contains pre-release code and may not be distributed.+ −
** You may use this file in accordance with the terms and conditions+ −
** contained in the Technology Preview License Agreement accompanying+ −
** this package.+ −
**+ −
** GNU Lesser General Public License Usage+ −
** Alternatively, this file may be used under the terms of the GNU Lesser+ −
** General Public License version 2.1 as published by the Free Software+ −
** Foundation and appearing in the file LICENSE.LGPL included in the+ −
** packaging of this file. Please review the following information to+ −
** ensure the GNU Lesser General Public License version 2.1 requirements+ −
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.+ −
**+ −
** In addition, as a special exception, Nokia gives you certain additional+ −
** rights. These rights are described in the Nokia Qt LGPL Exception+ −
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.+ −
**+ −
** If you have questions regarding the use of this file, please contact+ −
** Nokia at qt-info@nokia.com.+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
**+ −
** $QT_END_LICENSE$+ −
**+ −
****************************************************************************/+ −
+ −
/*!+ −
\page qtestlib-manual.html+ −
\title QTestLib Manual+ −
\brief An overview of Qt's unit testing framework.+ −
+ −
\ingroup frameworks-technologies+ −
\keyword qtestlib+ −
+ −
The QTestLib framework, provided by Nokia, is a tool for unit+ −
testing Qt based applications and libraries. QTestLib provides+ −
all the functionality commonly found in unit testing frameworks as+ −
well as extensions for testing graphical user interfaces.+ −
+ −
Table of contents:+ −
+ −
\tableofcontents+ −
+ −
\section1 QTestLib Features+ −
+ −
QTestLib is designed to ease the writing of unit tests for Qt+ −
based applications and libraries:+ −
+ −
\table+ −
\header \o Feature \o Details+ −
\row+ −
\o \bold Lightweight+ −
\o QTestLib consists of about 6000 lines of code and 60+ −
exported symbols.+ −
\row+ −
\o \bold Self-contained+ −
\o QTestLib requires only a few symbols from the Qt Core library+ −
for non-gui testing.+ −
\row+ −
\o \bold {Rapid testing}+ −
\o QTestLib needs no special test-runners; no special+ −
registration for tests.+ −
\row+ −
\o \bold {Data-driven testing}+ −
\o A test can be executed multiple times with different test data.+ −
\row+ −
\o \bold {Basic GUI testing}+ −
\o QTestLib offers functionality for mouse and keyboard simulation.+ −
\row+ −
\o \bold {Benchmarking}+ −
\o QTestLib supports benchmarking and provides several measurement back-ends.+ −
\row+ −
\o \bold {IDE friendly}+ −
\o QTestLib outputs messages that can be interpreted by Visual+ −
Studio and KDevelop.+ −
\row+ −
\o \bold Thread-safety+ −
\o The error reporting is thread safe and atomic.+ −
\row+ −
\o \bold Type-safety+ −
\o Extensive use of templates prevent errors introduced by+ −
implicit type casting.+ −
\row+ −
\o \bold {Easily extendable}+ −
\o Custom types can easily be added to the test data and test output.+ −
\endtable+ −
+ −
Note: For higher-level GUI and application testing needs, please+ −
see the \l{Third-Party Tools}{Qt testing products provided by+ −
Nokia partners}.+ −
+ −
+ −
\section1 QTestLib API+ −
+ −
All public methods are in the \l QTest namespace. In addition, the+ −
\l QSignalSpy class provides easy introspection for Qt's signals and slots.+ −
+ −
+ −
\section1 Using QTestLib+ −
+ −
\section2 Creating a Test+ −
+ −
To create a test, subclass QObject and add one or more private slots to it. Each+ −
private slot is a testfunction in your test. QTest::qExec() can be used to execute+ −
all testfunctions in the test object.+ −
+ −
In addition, there are four private slots that are \e not treated as testfunctions.+ −
They will be executed by the testing framework and can be used to initialize and+ −
clean up either the entire test or the current test function.+ −
+ −
\list+ −
\o \c{initTestCase()} will be called before the first testfunction is executed.+ −
\o \c{cleanupTestCase()} will be called after the last testfunction was executed.+ −
\o \c{init()} will be called before each testfunction is executed.+ −
\o \c{cleanup()} will be called after every testfunction.+ −
\endlist+ −
+ −
If \c{initTestCase()} fails, no testfunction will be executed. If \c{init()} fails,+ −
the following testfunction will not be executed, the test will proceed to the next+ −
testfunction.+ −
+ −
Example:+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 0+ −
+ −
For more examples, refer to the \l{QTestLib Tutorial}.+ −
+ −
\section2 Building a Test+ −
+ −
If you are using \c qmake as your build tool, just add the+ −
following to your project file:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 1+ −
+ −
If you are using other buildtools, make sure that you add the location+ −
of the QTestLib header files to your include path (usually \c{include/QtTest}+ −
under your Qt installation directory). If you are using a release build+ −
of Qt, link your test to the \c QtTest library. For debug builds, use+ −
\c{QtTest_debug}.+ −
+ −
See \l {Chapter 1: Writing a Unit Test}{Writing a Unit Test} for a step by+ −
step explanation.+ −
+ −
\section2 QTestLib Command Line Arguments+ −
+ −
\section3 Syntax+ −
+ −
The syntax to execute an autotest takes the following simple form:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 2+ −
+ −
Substitute \c testname with the name of your executable. \c+ −
testfunctions can contain names of test functions to be+ −
executed. If no \c testfunctions are passed, all tests are run. If you+ −
append the name of an entry in \c testdata, the test function will be+ −
run only with that test data.+ −
+ −
For example:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 3+ −
+ −
Runs the test function called \c toUpper with all available test data.+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 4+ −
+ −
Runs the \c toUpper test function with all available test data,+ −
and the \c toInt test function with the testdata called \c+ −
zero (if the specified test data doesn't exist, the associated test+ −
will fail).+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 5+ −
+ −
Runs the testMyWidget function test, outputs every signal+ −
emission and waits 500 milliseconds after each simulated+ −
mouse/keyboard event.+ −
+ −
\section3 Options+ −
+ −
The following command line arguments are understood:+ −
+ −
\list+ −
\o \c -help \BR+ −
outputs the possible command line arguments and give some useful help.+ −
\o \c -functions \BR+ −
outputs all test functions available in the test.+ −
\o \c -o \e filename \BR+ −
write output to the specified file, rather than to standard output+ −
\o \c -silent \BR+ −
silent output, only shows warnings, failures and minimal status messages+ −
\o \c -v1 \BR+ −
verbose output; outputs information on entering and exiting test functions.+ −
\o \c -v2 \BR+ −
extended verbose output; also outputs each \l QCOMPARE() and \l QVERIFY()+ −
\o \c -vs \BR+ −
outputs every signal that gets emitted+ −
\o \c -xml \BR+ −
outputs XML formatted results instead of plain text+ −
\o \c -lightxml \BR+ −
outputs results as a stream of XML tags+ −
\o \c -eventdelay \e ms \BR+ −
if no delay is specified for keyboard or mouse simulation+ −
(\l QTest::keyClick(),+ −
\l QTest::mouseClick() etc.), the value from this parameter+ −
(in milliseconds) is substituted.+ −
\o \c -keydelay \e ms \BR+ −
like -eventdelay, but only influences keyboard simulation and not mouse+ −
simulation.+ −
\o \c -mousedelay \e ms \BR+ −
like -eventdelay, but only influences mouse simulation and not keyboard+ −
simulation.+ −
\o \c -keyevent-verbose \BR+ −
output more verbose output for keyboard simulation+ −
\o \c -maxwarnings \e number\BR+ −
sets the maximum number of warnings to output. 0 for unlimited, defaults to 2000.+ −
\endlist+ −
+ −
\section2 Creating a Benchmark+ −
+ −
To create a benchmark, follow the instructions for crating a test and then add a+ −
QBENCHMARK macro to the test function that you want to benchmark.+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 12+ −
+ −
The code insde the QBENCHMARK macro will be measured, and possibly also repeated+ −
several times in order to get an accurate measurement. This depends on the selected+ −
measurement back-end. Several back-ends are available. They can be selected on the+ −
command line:+ −
+ −
\target testlib-benchmarking-measurement+ −
+ −
\table+ −
\header \o Name+ −
\o Commmand-line Argument+ −
\o Availability+ −
\row \o Walltime+ −
\o (default)+ −
\o All platforms+ −
\row \o CPU tick counter+ −
\o -tickcounter+ −
\o Windows, Mac OS X, Linux, many UNIX-like systems.+ −
\row \o Valgrind/Callgrind+ −
\o -callgrind+ −
\o Linux (if installed)+ −
\row \o Event Counter+ −
\o -eventcounter+ −
\o All platforms+ −
\endtable+ −
+ −
In short, walltime is always available but requires many repetitions to+ −
get a useful result. + −
Tick counters are usually available and can provide + −
results with fewer repetitions, but can be susceptible to CPU frequency + −
scaling issues. + −
Valgrind provides exact results, but does not take+ −
I/O waits into account, and is only available on a limited number of+ −
platforms.+ −
Event counting is available on all platforms and it provides the number of events+ −
that were received by the event loop before they are sent to their corresponding+ −
targets (this might include non-Qt events).+ −
+ −
\note Depending on the device configuration, Tick counters on the+ −
Windows CE platform may not be as fine-grained, compared to other platforms.+ −
Devices that do not support high-resolution timers default to+ −
one-millisecond granularity.+ −
+ −
See the chapter 5 in the \l{QTestLib Tutorial} for more benchmarking examples.+ −
+ −
\section1 Using QTestLib remotely on Windows CE+ −
\c cetest is a convenience application which helps the user to launch an + −
application remotely on a Windows CE device or emulator.+ −
+ −
It needs to be executed after the unit test has been successfully compiled.+ −
+ −
Prior to launching, the following files are copied to the device:+ −
+ −
\list+ −
\o all Qt libraries the project links to+ −
\o \l {QtRemote}{QtRemote.dll}+ −
\o the c runtime library specified during installation+ −
\o all files specified in the \c .pro file following the \l DEPLOYMENT rules.+ −
\endlist+ −
+ −
\section2 Using \c cetest+ −
\section3 Syntax+ −
The syntax to execute an autotest takes the following simple form:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 6+ −
+ −
\section3 Options+ −
\c cetest provides the same options as those for unit-testing on non cross-compiled+ −
platforms. See \l {QTestLib Command Line Arguments} {Command Line Arguments} for+ −
more information.+ −
+ −
The following commands are also included:+ −
+ −
\list+ −
\o \c -debug \BR+ −
Test version compiled in debug mode.+ −
\o \c -release \BR+ −
Test version compiled in release mode.+ −
\o \c -libpath \e path \BR+ −
Target path to copy Qt libraries to.+ −
\o \c -qt-delete \BR+ −
Delete Qt libraries after execution.+ −
\o \c -project-delete \BR+ −
Delete project files after execution.+ −
\o \c -delete \BR+ −
Delete project and Qt libraries after execution.+ −
\o \c -conf \BR+ −
Specifies a qt.conf file to be deployed to remote directory.+ −
\endlist+ −
+ −
\note \c{debug} is the default build option.+ −
+ −
\section2 QtRemote+ −
\c QtRemote is a small library which is build after QTestLib. It allows the host+ −
system to create a process on a remote device and waits until its execution has+ −
been finished.+ −
+ −
\section2 Requirements+ −
\c cetest uses Microsoft ActiveSync to establish a remote connection between the+ −
host computer and the device. Thus header files and libraries are needed to compile+ −
cetest and QtRemote successfully.+ −
+ −
Prior to \l{Installing Qt on Windows CE}{installation} of Qt, you need to set your+ −
\c INCLUDE and \c LIB environment variables properly.+ −
+ −
A default installation of Windows Mobile 5 for Pocket PC can be obtained by:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 7+ −
+ −
Note that Qt will remember the path, so you do not need to set it again+ −
after switching the environments for cross-compilation.+ −
+ −
\section1 3rd Party Code+ −
+ −
The CPU tick counters used for benchmarking is licensed under the following+ −
license: (from src/testlib/3rdparty/cycle.h)+ −
+ −
\legalese+ −
Copyright (c) 2003, 2006 Matteo Frigo\br+ −
Copyright (c) 2003, 2006 Massachusetts Institute of Technology+ −
+ −
Permission is hereby granted, free of charge, to any person obtaining+ −
a copy of this software and associated documentation files (the+ −
"Software"), to deal in the Software without restriction, including+ −
without limitation the rights to use, copy, modify, merge, publish,+ −
distribute, sublicense, and/or sell copies of the Software, and to+ −
permit persons to whom the Software is furnished to do so, subject to+ −
the following conditions:+ −
+ −
The above copyright notice and this permission notice shall be+ −
included in all copies or substantial portions of the Software.+ −
+ −
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+ −
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+ −
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+ −
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE+ −
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION+ −
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION+ −
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+ −
\endlegalese+ −
*/+ −
+ −
/*!+ −
\page qtestlib-tutorial.html+ −
\brief A short introduction to testing with QTestLib.+ −
\contentspage QTestLib Manual+ −
\nextpage {Chapter 1: Writing a Unit Test}{Chapter 1}+ −
+ −
\title QTestLib Tutorial+ −
+ −
This tutorial gives a short introduction to how to use some of the+ −
features of the QTestLib framework. It is divided into four+ −
chapters:+ −
+ −
\list 1+ −
\o \l {Chapter 1: Writing a Unit Test}{Writing a Unit Test}+ −
\o \l {Chapter 2: Data Driven Testing}{Data Driven Testing}+ −
\o \l {Chapter 3: Simulating GUI Events}{Simulating GUI Events}+ −
\o \l {Chapter 4: Replaying GUI Events}{Replaying GUI Events}+ −
\o \l {Chapter 5: Writing a Benchmark}{Writing a Benchmark}+ −
\endlist+ −
+ −
*/+ −
+ −
+ −
/*!+ −
\example qtestlib/tutorial1+ −
+ −
\contentspage {QTestLib Tutorial}{Contents}+ −
\nextpage {Chapter 2: Data Driven Testing}{Chapter 2}+ −
+ −
\title Chapter 1: Writing a Unit Test+ −
+ −
In this first chapter we will see how to write a simple unit test+ −
for a class, and how to execute it.+ −
+ −
\section1 Writing a Test+ −
+ −
Let's assume you want to test the behavior of our QString class.+ −
First, you need a class that contains your test functions. This class+ −
has to inherit from QObject:+ −
+ −
\snippet examples/qtestlib/tutorial1/testqstring.cpp 0+ −
+ −
Note that you need to include the QTest header, and that the+ −
test functions have to be declared as private slots so the+ −
test framework finds and executes it.+ −
+ −
Then you need to implement the test function itself. The+ −
implementation could look like this:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 8+ −
+ −
The \l QVERIFY() macro evaluates the expression passed as its+ −
argument. If the expression evaluates to true, the execution of+ −
the test function continues. Otherwise, a message describing the+ −
failure is appended to the test log, and the test function stops+ −
executing.+ −
+ −
But if you want a more verbose output to the test log, you should+ −
use the \l QCOMPARE() macro instead:+ −
+ −
\snippet examples/qtestlib/tutorial1/testqstring.cpp 1+ −
+ −
If the strings are not equal, the contents of both strings is+ −
appended to the test log, making it immediately visible why the+ −
comparison failed.+ −
+ −
Finally, to make our test case a stand-alone executable, the+ −
following two lines are needed:+ −
+ −
\snippet examples/qtestlib/tutorial1/testqstring.cpp 2+ −
+ −
The \l QTEST_MAIN() macro expands to a simple \c main()+ −
method that runs all the test functions. Note that if both the+ −
declaration and the implementation of our test class are in a \c+ −
.cpp file, we also need to include the generated moc file to make+ −
Qt's introspection work.+ −
+ −
\section1 Executing a Test+ −
+ −
Now that we finished writing our test, we want to execute+ −
it. Assuming that our test was saved as \c testqstring.cpp in an+ −
empty directory: we build the test using qmake to create a project+ −
and generate a makefile.+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 9+ −
+ −
\bold {Note:}If you're using windows, replace \c make with \c+ −
nmake or whatever build tool you use.+ −
+ −
Running the resulting executable should give you the following+ −
output:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 10+ −
+ −
Congratulations! You just wrote and executed your first unit test+ −
using the QTestLib framework.+ −
*/+ −
+ −
/*!+ −
\example qtestlib/tutorial2+ −
+ −
\previouspage {Chapter 1: Writing a Unit Test}{Chapter 1}+ −
\contentspage {QTestLib Tutorial}{Contents}+ −
\nextpage {Chapter 3: Simulating Gui Events}{Chapter 3}+ −
+ −
\title Chapter 2: Data Driven Testing+ −
+ −
In this chapter we will demonstrate how to execute a test+ −
multiple times with different test data.+ −
+ −
So far, we have hard coded the data we wanted to test into our+ −
test function. If we add more test data, the function might look like+ −
this:+ −
+ −
\snippet doc/src/snippets/code/doc_src_qtestlib.qdoc 11+ −
+ −
To prevent that the function ends up being cluttered by repetitive+ −
code, QTestLib supports adding test data to a test function. All+ −
we need is to add another private slot to our test class:+ −
+ −
\snippet examples/qtestlib/tutorial2/testqstring.cpp 0+ −
+ −
\section1 Writing the Data Function+ −
+ −
A test function's associated data function carries the same name,+ −
appended by \c{_data}. Our data function looks like this:+ −
+ −
\snippet examples/qtestlib/tutorial2/testqstring.cpp 1+ −
+ −
First, we define the two elements of our test table using the \l+ −
QTest::addColumn() function: A test string, and the+ −
expected result of applying the QString::toUpper() function to+ −
that string.+ −
+ −
Then we add some data to the table using the \l+ −
QTest::newRow() function. Each set of data will become a+ −
separate row in the test table.+ −
+ −
\l QTest::newRow() takes one argument: A name that will be+ −
associated with the data set. If the test fails, the name will be+ −
used in the test log, referencing the failed data. Then we+ −
stream the data set into the new table row: First an arbitrary+ −
string, and then the expected result of applying the+ −
QString::toUpper() function to that string.+ −
+ −
You can think of the test data as a two-dimensional table. In+ −
our case, it has two columns called \c string and \c result and+ −
three rows. In addition a name as well as an index is associated+ −
with each row:+ −
+ −
\table+ −
\header+ −
\o index+ −
\o name+ −
\o string+ −
\o result+ −
\row+ −
\o 0+ −
\o all lower+ −
\o "hello"+ −
\o HELLO+ −
\row+ −
\o 1+ −
\o mixed+ −
\o "Hello"+ −
\o HELLO+ −
\row+ −
\o 2+ −
\o all upper+ −
\o "HELLO"+ −
\o HELLO+ −
\endtable+ −
+ −
\section1 Rewriting the Test Function+ −
+ −
Our test function can now be rewritten:+ −
+ −
\snippet examples/qtestlib/tutorial2/testqstring.cpp 2+ −
+ −
The TestQString::toUpper() function will be executed three times,+ −
once for each entry in the test table that we created in the+ −
associated TestQString::toUpper_data() function.+ −
+ −
First, we fetch the two elements of the data set using the \l+ −
QFETCH() macro. \l QFETCH() takes two arguments: The data type of+ −
the element and the element name. Then we perform the test using+ −
the \l QCOMPARE() macro.+ −
+ −
This approach makes it very easy to add new data to the test+ −
without modifying the test itself.+ −
+ −
And again, to make our test case a stand-alone executable,+ −
the following two lines are needed:+ −
+ −
\snippet examples/qtestlib/tutorial2/testqstring.cpp 3+ −
+ −
As before, the QTEST_MAIN() macro expands to a simple main()+ −
method that runs all the test functions, and since both the+ −
declaration and the implementation of our test class are in a .cpp+ −
file, we also need to include the generated moc file to make Qt's+ −
introspection work.+ −
*/+ −
+ −
/*!+ −
\example qtestlib/tutorial3+ −
+ −
\previouspage {Chapter 2 Data Driven Testing}{Chapter 2}+ −
\contentspage {QTestLib Tutorial}{Contents}+ −
\nextpage {Chapter 4: Replaying GUI Events}{Chapter 4}+ −
+ −
\title Chapter 3: Simulating GUI Events+ −
+ −
QTestLib features some mechanisms to test graphical user+ −
interfaces. Instead of simulating native window system events,+ −
QTestLib sends internal Qt events. That means there are no+ −
side-effects on the machine the tests are running on.+ −
+ −
In this chapter we will se how to write a simple GUI test.+ −
+ −
\section1 Writing a GUI test+ −
+ −
This time, let's assume you want to test the behavior of our+ −
QLineEdit class. As before, you will need a class that contains+ −
your test function:+ −
+ −
\snippet examples/qtestlib/tutorial3/testgui.cpp 0+ −
+ −
The only difference is that you need to include the QtGui class+ −
definitions in addition to the QTest namespace.+ −
+ −
\snippet examples/qtestlib/tutorial3/testgui.cpp 1+ −
+ −
In the implementation of the test function we first create a+ −
QLineEdit. Then we simulate writing "hello world" in the line edit+ −
using the \l QTest::keyClicks() function.+ −
+ −
\note The widget must also be shown in order to correctly test keyboard+ −
shortcuts.+ −
+ −
QTest::keyClicks() simulates clicking a sequence of keys on a+ −
widget. Optionally, a keyboard modifier can be specified as well+ −
as a delay (in milliseconds) of the test after each key click. In+ −
a similar way, you can use the QTest::keyClick(),+ −
QTest::keyPress(), QTest::keyRelease(), QTest::mouseClick(),+ −
QTest::mouseDClick(), QTest::mouseMove(), QTest::mousePress()+ −
and QTest::mouseRelease() functions to simulate the associated+ −
GUI events.+ −
+ −
Finally, we use the \l QCOMPARE() macro to check if the line edit's+ −
text is as expected.+ −
+ −
As before, to make our test case a stand-alone executable, the+ −
following two lines are needed:+ −
+ −
\snippet examples/qtestlib/tutorial3/testgui.cpp 2+ −
+ −
The QTEST_MAIN() macro expands to a simple main() method that+ −
runs all the test functions, and since both the declaration and+ −
the implementation of our test class are in a .cpp file, we also+ −
need to include the generated moc file to make Qt's introspection+ −
work.+ −
*/+ −
+ −
/*!+ −
\example qtestlib/tutorial4+ −
+ −
\previouspage {Chapter 3: Simulating GUI Event}{Chapter 3}+ −
\contentspage {QTestLib Tutorial}{Contents}+ −
\nextpage {Chapter 5: Writing a Benchmark}{Chapter 5}+ −
+ −
\title Chapter 4: Replaying GUI Events+ −
+ −
In this chapter, we will show how to simulate a GUI event,+ −
and how to store a series of GUI events as well as replay them on+ −
a widget.+ −
+ −
The approach to storing a series of events and replay them, is+ −
quite similar to the approach explained in \l {Chapter 2:+ −
Data Driven Testing}{chapter 2}; all you need is to add a data+ −
function to your test class:+ −
+ −
\snippet examples/qtestlib/tutorial4/testgui.cpp 0+ −
+ −
\section1 Writing the Data Function+ −
+ −
As before, a test function's associated data function carries the+ −
same name, appended by \c{_data}.+ −
+ −
\snippet examples/qtestlib/tutorial4/testgui.cpp 1+ −
+ −
First, we define the elements of the table using the+ −
QTest::addColumn() function: A list of GUI events, and the+ −
expected result of applying the list of events on a QWidget. Note+ −
that the type of the first element is \l QTestEventList.+ −
+ −
A QTestEventList can be populated with GUI events that can be+ −
stored as test data for later usage, or be replayed on any+ −
QWidget.+ −
+ −
In our current data function, we create two \l+ −
{QTestEventList}s. The first list consists of a single click to+ −
the 'a' key. We add the event to the list using the+ −
QTestEventList::addKeyClick() function. Then we use the+ −
QTest::newRow() function to give the data set a name, and+ −
stream the event list and the expected result into the table.+ −
+ −
The second list consists of two key clicks: an 'a' with a+ −
following 'backspace'. Again we use the+ −
QTestEventList::addKeyClick() to add the events to the list, and+ −
QTest::newRow() to put the event list and the expected+ −
result into the table with an associated name.+ −
+ −
\section1 Rewriting the Test Function+ −
+ −
Our test can now be rewritten:+ −
+ −
\snippet examples/qtestlib/tutorial4/testgui.cpp 2+ −
+ −
The TestGui::testGui() function will be executed two times,+ −
once for each entry in the test data that we created in the+ −
associated TestGui::testGui_data() function.+ −
+ −
First, we fetch the two elements of the data set using the \l+ −
QFETCH() macro. \l QFETCH() takes two arguments: The data type of+ −
the element and the element name. Then we create a QLineEdit, and+ −
apply the list of events on that widget using the+ −
QTestEventList::simulate() function.+ −
+ −
Finally, we use the QCOMPARE() macro to check if the line edit's+ −
text is as expected.+ −
+ −
As before, to make our test case a stand-alone executable,+ −
the following two lines are needed:+ −
+ −
\snippet examples/qtestlib/tutorial4/testgui.cpp 3+ −
+ −
The QTEST_MAIN() macro expands to a simple main() method that+ −
runs all the test functions, and since both the declaration and+ −
the implementation of our test class are in a .cpp file, we also+ −
need to include the generated moc file to make Qt's introspection+ −
work.+ −
*/+ −
+ −
/*!+ −
\example qtestlib/tutorial5+ −
+ −
\previouspage {Chapter 4: Replaying GUI Events}{Chapter 4}+ −
\contentspage {QTestLib Tutorial}{Contents}+ −
+ −
\title Chapter 5: Writing a Benchmark+ −
+ −
In this final chapter we will demonstrate how to write benchmarks+ −
using QTestLib.+ −
+ −
\section1 Writing a Benchmark+ −
To create a benchmark we extend a test function with a QBENCHMARK macro.+ −
A benchmark test function will then typically consist of setup code and + −
a QBENCHMARK macro that contains the code to be measured. This test+ −
function benchmarks QString::localeAwareCompare().+ −
+ −
\snippet examples/qtestlib/tutorial5/benchmarking.cpp 0+ −
+ −
Setup can be done at the beginning of the function, the clock is not + −
running at this point. The code inside the QBENCHMARK macro will be+ −
measured, and possibly repeated several times in order to get an + −
accurate measurement.+ −
+ −
Several \l {testlib-benchmarking-measurement}{back-ends} are available+ −
and can be selected on the command line.+ −
+ −
\section1 Data Functions+ −
+ −
Data functions are useful for creating benchmarks that compare + −
multiple data inputs, for example locale aware compare against standard+ −
compare.+ −
+ −
\snippet examples/qtestlib/tutorial5/benchmarking.cpp 1+ −
+ −
The test function then uses the data to determine what to benchmark.+ −
+ −
\snippet examples/qtestlib/tutorial5/benchmarking.cpp 2+ −
+ −
The "if(useLocaleCompare)" switch is placed outside the QBENCHMARK + −
macro to avoid measuring its overhead. Each benchmark test function+ −
can have one active QBENCHMARK macro. + −
+ −
\section1 External Tools+ −
+ −
Tools for handling and visualizing test data are available as part of+ −
the \l{qtestlib-tools} project on the Qt Labs Web site. These include+ −
a tool for comparing performance data obtained from test runs and a+ −
utility to generate Web-based graphs of performance data.+ −
+ −
See the \l{qtestlib-tools Announcement} for more information on these+ −
tools and a simple graphing example.+ −
+ −
*/+ −
+ −
+ −
+ −