doc/src/development/qtestlib.qdoc
branchRCL_3
changeset 8 3f74d0d4af4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/development/qtestlib.qdoc	Thu Apr 08 14:19:33 2010 +0300
@@ -0,0 +1,778 @@
+/****************************************************************************
+**
+** 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.
+
+*/
+
+
+