diff options
Diffstat (limited to 'doc/src/development/qtestlib.qdoc')
-rw-r--r-- | doc/src/development/qtestlib.qdoc | 778 |
1 files changed, 778 insertions, 0 deletions
diff --git a/doc/src/development/qtestlib.qdoc b/doc/src/development/qtestlib.qdoc new file mode 100644 index 0000000..13a5b7c --- /dev/null +++ b/doc/src/development/qtestlib.qdoc @@ -0,0 +1,778 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $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 an can be selected on the + command line: + + \target testlib-benchmarking-measurement + + \table + \header \o Name + \o Commmand-line Arguemnt + \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. + +*/ + + + |