1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtTest module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
42 #include <QtTest/qtestcase.h>
43 #include <QtTest/qtestassert.h>
45 #include <QtCore/qbytearray.h>
46 #include <QtCore/qmetaobject.h>
47 #include <QtCore/qobject.h>
48 #include <QtCore/qstringlist.h>
49 #include <QtCore/qvector.h>
50 #include <QtCore/qvarlengtharray.h>
51 #include <QtCore/qcoreapplication.h>
52 #include <QtCore/qfile.h>
53 #include <QtCore/qfileinfo.h>
54 #include <QtCore/qdir.h>
55 #include <QtCore/qprocess.h>
56 #include <QtCore/qdebug.h>
57 #include <QtCore/qlibraryinfo.h>
59 #include <QtTest/private/qtestlog_p.h>
60 #include <QtTest/private/qtesttable_p.h>
61 #include <QtTest/qtestdata.h>
62 #include <QtTest/private/qtestresult_p.h>
63 #include <QtTest/private/qsignaldumper_p.h>
64 #include <QtTest/private/qbenchmark_p.h>
65 #include <QtTest/private/cycle_p.h>
73 # if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR))
77 #include <windows.h> // for Sleep
86 #include <IOKit/pwr_mgt/IOPMLib.h>
95 \brief The QTest namespace contains all the functions and
96 declarations that are related to Qt Test.
98 See the \l{Qt Test Overview} for information about how to write unit tests.
101 /*! \macro QVERIFY(condition)
105 The QVERIFY() macro checks whether the \a condition is true or not. If it is
106 true, execution continues. If not, a failure is recorded in the test log
107 and the test won't be executed further.
109 \b {Note:} This macro can only be used in a test function that is invoked
110 by the test framework.
113 \snippet code/src_qtestlib_qtestcase.cpp 0
115 \sa QCOMPARE(), QTRY_VERIFY()
118 /*! \macro QVERIFY2(condition, message)
122 The QVERIFY2() macro behaves exactly like QVERIFY(), except that it outputs
123 a verbose \a message when \a condition is false. The \a message is a plain
127 \snippet code/src_qtestlib_qtestcase.cpp 1
129 \sa QVERIFY(), QCOMPARE()
132 /*! \macro QCOMPARE(actual, expected)
136 The QCOMPARE macro compares an \a actual value to an \a expected value using
137 the equals operator. If \a actual and \a expected are identical, execution
138 continues. If not, a failure is recorded in the test log and the test
139 won't be executed further.
141 In the case of comparing floats and doubles, qFuzzyCompare() is used for
142 comparing. This means that comparing to 0 will likely fail. One solution
143 to this is to compare to 1, and add 1 to the produced output.
145 QCOMPARE tries to output the contents of the values if the comparison fails,
146 so it is visible from the test log why the comparison failed.
148 QCOMPARE is very strict on the data types. Both \a actual and \a expected
149 have to be of the same type, otherwise the test won't compile. This prohibits
150 unspecified behavior from being introduced; that is behavior that usually
151 occurs when the compiler implicitly casts the argument.
153 For your own classes, you can use \l QTest::toString() to format values for
154 outputting into the test log.
156 \note This macro can only be used in a test function that is invoked
157 by the test framework.
160 \snippet code/src_qtestlib_qtestcase.cpp 2
162 \sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
165 /*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
170 The QTRY_VERIFY_WITH_TIMEOUT() macro is similar to QVERIFY(), but checks the \a condition
171 repeatedly, until either the condition becomes true or the \a timeout is
172 reached. Between each evaluation, events will be processed. If the timeout
173 is reached, a failure is recorded in the test log and the test won't be
176 \note This macro can only be used in a test function that is invoked
177 by the test framework.
179 \sa QTRY_VERIFY(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
183 /*! \macro QTRY_VERIFY(condition)
188 Invokes QTRY_VERIFY_WITH_TIMEOUT() with a timeout of five seconds.
190 \note This macro can only be used in a test function that is invoked
191 by the test framework.
193 \sa QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
196 /*! \macro QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout)
201 The QTRY_COMPARE_WITH_TIMEOUT() macro is similar to QCOMPARE(), but performs the comparison
202 of the \a actual and \a expected values repeatedly, until either the two values
203 are equal or the \a timeout is reached. Between each comparison, events
204 will be processed. If the timeout is reached, a failure is recorded in the
205 test log and the test won't be executed further.
207 \note This macro can only be used in a test function that is invoked
208 by the test framework.
210 \sa QTRY_COMPARE(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
213 /*! \macro QTRY_COMPARE(actual, expected)
218 Invokes QTRY_COMPARE_WITH_TIMEOUT() with a timeout of five seconds.
220 \note This macro can only be used in a test function that is invoked
221 by the test framework.
223 \sa QTRY_COMPARE_WITH_TIMEOUT(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
226 /*! \macro QFETCH(type, name)
230 The fetch macro creates a local variable named \a name with the type \a type
231 on the stack. \a name has to match the element name from the test's data.
232 If no such element exists, the test will assert.
234 Assuming a test has the following data:
236 \snippet code/src_qtestlib_qtestcase.cpp 3
238 The test data has two elements, a QString called \c aString and an integer
239 called \c expected. To fetch these values in the actual test:
241 \snippet code/src_qtestlib_qtestcase.cpp 4
243 \c aString and \c expected are variables on the stack that are initialized with
244 the current test data.
246 \b {Note:} This macro can only be used in a test function that is invoked
247 by the test framework. The test function must have a _data function.
250 /*! \macro QWARN(message)
255 Appends \a message as a warning to the test log. This macro can be used anywhere
259 /*! \macro QFAIL(message)
263 This macro can be used to force a test failure. The test stops
264 executing and the failure \a message is appended to the test log.
266 \b {Note:} This macro can only be used in a test function that is invoked
267 by the test framework.
271 \snippet code/src_qtestlib_qtestcase.cpp 5
274 /*! \macro QTEST(actual, testElement)
278 QTEST() is a convenience macro for \l QCOMPARE() that compares
279 the value \a actual with the element \a testElement from the test's data.
280 If there is no such element, the test asserts.
282 Apart from that, QTEST() behaves exactly as \l QCOMPARE().
286 \snippet code/src_qtestlib_qtestcase.cpp 6
290 \snippet code/src_qtestlib_qtestcase.cpp 7
295 /*! \macro QSKIP(description)
299 If called from a test function, the QSKIP() macro stops execution of the test
300 without adding a failure to the test log. You can use it to skip tests that
301 wouldn't make sense in the current configuration. The text \a description is
302 appended to the test log and should contain an explanation of why the test
303 couldn't be executed.
305 If the test is data-driven, each call to QSKIP() will skip only the current
306 row of test data, so an unconditional call to QSKIP will produce one skip
307 message in the test log for each row of test data.
309 If called from an _data function, the QSKIP() macro will stop execution of
310 the _data function and will prevent execution of the associated test
313 If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
314 skip all test and _data functions.
316 \b {Note:} This macro can only be used in a test function or _data
317 function that is invoked by the test framework.
320 \snippet code/src_qtestlib_qtestcase.cpp 8
323 /*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
327 The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
328 expected failure. Instead of adding a failure to the test log, an expected
329 failure will be reported.
331 If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
332 but passes instead, an unexpected pass (XPASS) is written to the test log.
334 The parameter \a dataIndex describes for which entry in the test data the
335 failure is expected. Pass an empty string (\c{""}) if the failure
336 is expected for all entries or if no test data exists.
338 \a comment will be appended to the test log for the expected failure.
340 \a mode is a \l QTest::TestFailMode and sets whether the test should
341 continue to execute or not.
343 \b {Note:} This macro can only be used in a test function that is invoked
344 by the test framework.
347 \snippet code/src_qtestlib_qtestcase.cpp 9
349 In the example above, an expected fail will be written into the test output
350 if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
351 is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
352 statement in the example.
355 \snippet code/src_qtestlib_qtestcase.cpp 10
357 The above testfunction will not continue executing for the test data
360 \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
363 /*! \macro QFINDTESTDATA(filename)
368 Returns a QString for the testdata file referred to by \a filename, or an
369 empty QString if the testdata file could not be found.
371 This macro allows the test to load data from an external file without
372 hardcoding an absolute filename into the test, or using relative paths
373 which may be error prone.
375 The returned path will be the first path from the following list which
376 resolves to an existing file or directory:
379 \li \a filename relative to QCoreApplication::applicationDirPath()
380 (only if a QCoreApplication or QApplication object has been created).
381 \li \a filename relative to the test's standard install directory
382 (QLibraryInfo::TestsPath with the lowercased testcase name appended).
383 \li \a filename relative to the directory containing the source file from which
384 QFINDTESTDATA is invoked.
387 If the named file/directory does not exist at any of these locations,
388 a warning is printed to the test log.
390 For example, in this code:
391 \snippet code/src_qtestlib_qtestcase.cpp 26
393 The testdata file will be resolved as the first existing file from:
396 \li \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
397 \li \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
398 \li \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
401 This allows the test to find its testdata regardless of whether the
402 test has been installed, and regardless of whether the test's build tree
403 is equal to the test's source tree.
405 \b {Note:} reliable detection of testdata from the source directory requires
406 either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
407 point to the working directory from which the compiler is invoked, or only
408 absolute paths to the source files are passed to the compiler. Otherwise, the
409 absolute path of the source directory cannot be determined.
411 \b {Note:} For tests that use the \l QTEST_APPLESS_MAIN() macro to generate a
412 \c{main()} function, \c{QFINDTESTDATA} will not attempt to find test data
413 relative to QCoreApplication::applicationDirPath(). In practice, this means that
414 tests using \c{QTEST_APPLESS_MAIN()} will fail to find their test data
415 if run from a shadow build tree.
418 /*! \macro QTEST_MAIN(TestClass)
422 Implements a main() function that instantiates an application object and
423 the \a TestClass, and executes all tests in the order they were defined.
424 Use this macro to build stand-alone executables.
426 If \c QT_WIDGETS_LIB is defined, the application object will be a QApplication,
427 if \c QT_GUI_LIB is defined, the application object will be a QGuiApplication,
428 otherwise it will be a QCoreApplication. If qmake is used and the configuration
429 includes \c{QT += widgets}, then \c QT_WIDGETS_LIB will be defined automatically.
430 Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
431 \c QT_GUI_LIB will be defined automatically.
433 \b {Note:} On platforms that have keypad navigation enabled by default,
434 this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
435 to simplify the usage of key events when writing autotests. If you wish to write a
436 test case that uses keypad navigation, you should enable it either in the
437 \c {initTestCase()} or \c {init()} functions of your test case by calling
438 \l {QApplication::setNavigationMode()}.
441 \snippet code/src_qtestlib_qtestcase.cpp 11
443 \sa QTEST_APPLESS_MAIN(), QTEST_GUILESS_MAIN(), QTest::qExec(),
444 QApplication::setNavigationMode()
447 /*! \macro QTEST_APPLESS_MAIN(TestClass)
451 Implements a main() function that executes all tests in \a TestClass.
453 Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
454 object. Use this macro for really simple stand-alone non-GUI tests.
459 /*! \macro QTEST_GUILESS_MAIN(TestClass)
464 Implements a main() function that instantiates a QCoreApplication object
465 and the \a TestClass, and executes all tests in the order they were
466 defined. Use this macro to build stand-alone executables.
468 Behaves like \l QTEST_MAIN(), but instantiates a QCoreApplication instead
469 of the QApplication object. Use this macro if your test case doesn't need
470 functionality offered by QApplication, but the event loop is still necessary.
480 This macro is used to measure the performance of code within a test.
481 The code to be benchmarked is contained within a code block following
486 \snippet code/src_qtestlib_qtestcase.cpp 27
488 \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
489 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
493 \macro QBENCHMARK_ONCE
498 \brief The QBENCHMARK_ONCE macro is for measuring performance of a
499 code block by running it once.
501 This macro is used to measure the performance of code within a test.
502 The code to be benchmarked is contained within a code block following
505 Unlike QBENCHMARK, the contents of the contained code block is only run
506 once. The elapsed time will be reported as "0" if it's to short to
507 be measured by the selected backend. (Use)
509 \sa {Qt Test Overview#Creating a Benchmark}{Creating a Benchmark},
510 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
513 /*! \enum QTest::TestFailMode
515 This enum describes the modes for handling an expected failure of the
516 \l QVERIFY() or \l QCOMPARE() macros.
518 \value Abort Aborts the execution of the test. Use this mode when it
519 doesn't make sense to execute the test any further after the
522 \value Continue Continues execution of the test after the expected failure.
527 /*! \enum QTest::KeyAction
529 This enum describes possible actions for key handling.
531 \value Press The key is pressed.
532 \value Release The key is released.
533 \value Click The key is clicked (pressed and released).
536 /*! \enum QTest::MouseAction
538 This enum describes possible actions for mouse handling.
540 \value MousePress A mouse button is pressed.
541 \value MouseRelease A mouse button is released.
542 \value MouseClick A mouse button is clicked (pressed and released).
543 \value MouseDClick A mouse button is double clicked (pressed and released twice).
544 \value MouseMove The mouse pointer has moved.
547 /*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
551 Simulates clicking of \a key with an optional \a modifier on a \a widget.
552 If \a delay is larger than 0, the test will wait for \a delay milliseconds
553 before clicking the key.
556 \snippet code/src_qtestlib_qtestcase.cpp 13
558 The example above simulates clicking \c a on \c myWidget without
559 any keyboard modifiers and without delay of the test.
561 \sa QTest::keyClicks()
564 /*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
566 Simulates clicking of \a key with an optional \a modifier on a \a widget.
567 If \a delay is larger than 0, the test will wait for \a delay milliseconds
568 before clicking the key.
571 \snippet code/src_qtestlib_qtestcase.cpp 14
573 The first example above simulates clicking the \c escape key on \c
574 myWidget without any keyboard modifiers and without delay. The
575 second example simulates clicking \c shift-escape on \c myWidget
576 following a 200 ms delay of the test.
578 \sa QTest::keyClicks()
581 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
583 Sends a Qt key event to \a widget with the given \a key and an associated \a action.
584 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
585 (in milliseconds) of the test before sending the event.
588 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
592 Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action.
593 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
594 (in milliseconds) of the test before sending the event.
598 /*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
600 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
601 is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
603 \b {Note:} At some point you should release the key using \l keyRelease().
605 \sa QTest::keyRelease(), QTest::keyClick()
608 /*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
612 Simulates pressing a \a key with an optional \a modifier on a \a widget.
613 If \a delay is larger than 0, the test will wait for \a delay milliseconds
614 before pressing the key.
616 \b {Note:} At some point you should release the key using \l keyRelease().
618 \sa QTest::keyRelease(), QTest::keyClick()
621 /*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
623 Simulates releasing a \a key with an optional \a modifier on a \a widget.
624 If \a delay is larger than 0, the test will wait for \a delay milliseconds
625 before releasing the key.
627 \sa QTest::keyPress(), QTest::keyClick()
630 /*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
634 Simulates releasing a \a key with an optional \a modifier on a \a widget.
635 If \a delay is larger than 0, the test will wait for \a delay milliseconds
636 before releasing the key.
638 \sa QTest::keyClick()
642 /*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
644 Simulates clicking a \a sequence of keys on a \a
645 widget. Optionally, a keyboard \a modifier can be specified as
646 well as a \a delay (in milliseconds) of the test before each key
650 \snippet code/src_qtestlib_qtestcase.cpp 15
652 The example above simulates clicking the sequence of keys
653 representing "hello world" on \c myWidget without any keyboard
654 modifiers and without delay of the test.
656 \sa QTest::keyClick()
659 /*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
661 Simulates pressing a mouse \a button with an optional \a modifier
662 on a \a widget. The position is defined by \a pos; the default
663 position is the center of the widget. If \a delay is specified,
664 the test will wait for the specified amount of milliseconds before
667 \sa QTest::mouseRelease(), QTest::mouseClick()
670 /*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
672 Simulates releasing a mouse \a button with an optional \a modifier
673 on a \a widget. The position of the release is defined by \a pos;
674 the default position is the center of the widget. If \a delay is
675 specified, the test will wait for the specified amount of
676 milliseconds before releasing the button.
678 \sa QTest::mousePress(), QTest::mouseClick()
681 /*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
683 Simulates clicking a mouse \a button with an optional \a modifier
684 on a \a widget. The position of the click is defined by \a pos;
685 the default position is the center of the widget. If \a delay is
686 specified, the test will wait for the specified amount of
687 milliseconds before pressing and before releasing the button.
689 \sa QTest::mousePress(), QTest::mouseRelease()
692 /*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
694 Simulates double clicking a mouse \a button with an optional \a
695 modifier on a \a widget. The position of the click is defined by
696 \a pos; the default position is the center of the widget. If \a
697 delay is specified, the test will wait for the specified amount of
698 milliseconds before each press and release.
700 \sa QTest::mouseClick()
703 /*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
705 Moves the mouse pointer to a \a widget. If \a pos is not
706 specified, the mouse pointer moves to the center of the widget. If
707 a \a delay (in milliseconds) is given, the test will wait before
708 moving the mouse pointer.
712 \fn char *QTest::toString(const T &value)
714 Returns a textual representation of \a value. This function is used by
715 \l QCOMPARE() to output verbose information in case of a test failure.
717 You can add specializations of this function to your test to enable
720 \b {Note:} The caller of toString() must delete the returned data
721 using \c{delete[]}. Your implementation should return a string
722 created with \c{new[]} or qstrdup().
726 \snippet code/src_qtestlib_qtestcase.cpp 16
728 The example above defines a toString() specialization for a class
729 called \c MyPoint. Whenever a comparison of two instances of \c
730 MyPoint fails, \l QCOMPARE() will call this function to output the
731 contents of \c MyPoint to the test log.
737 \fn char *QTest::toString(const QLatin1String &string)
740 Returns a textual representation of the given \a string.
744 \fn char *QTest::toString(const QString &string)
747 Returns a textual representation of the given \a string.
751 \fn char *QTest::toString(const QByteArray &ba)
754 Returns a textual representation of the byte array \a ba.
756 \sa QTest::toHexRepresentation()
760 \fn char *QTest::toString(const QTime &time)
763 Returns a textual representation of the given \a time.
767 \fn char *QTest::toString(const QDate &date)
770 Returns a textual representation of the given \a date.
774 \fn char *QTest::toString(const QDateTime &dateTime)
777 Returns a textual representation of the date and time specified by
782 \fn char *QTest::toString(const QChar &character)
785 Returns a textual representation of the given \a character.
789 \fn char *QTest::toString(const QPoint &point)
792 Returns a textual representation of the given \a point.
796 \fn char *QTest::toString(const QSize &size)
799 Returns a textual representation of the given \a size.
803 \fn char *QTest::toString(const QRect &rectangle)
806 Returns a textual representation of the given \a rectangle.
810 \fn char *QTest::toString(const QUrl &url)
814 Returns a textual representation of the given \a url.
818 \fn char *QTest::toString(const QPointF &point)
821 Returns a textual representation of the given \a point.
825 \fn char *QTest::toString(const QSizeF &size)
828 Returns a textual representation of the given \a size.
832 \fn char *QTest::toString(const QRectF &rectangle)
835 Returns a textual representation of the given \a rectangle.
839 \fn char *QTest::toString(const QVariant &variant)
842 Returns a textual representation of the given \a variant.
845 /*! \fn void QTest::qWait(int ms)
847 Waits for \a ms milliseconds. While waiting, events will be processed and
848 your test will stay responsive to user interface events or network communication.
851 \snippet code/src_qtestlib_qtestcase.cpp 17
853 The code above will wait until the network server is responding for a
854 maximum of about 12.5 seconds.
856 \sa QTest::qSleep(), QSignalSpy::wait()
859 /*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
862 Waits for \a timeout milliseconds or until the \a window is exposed.
863 Returns true if \c window is exposed within \a timeout milliseconds, otherwise returns false.
865 This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
866 time after being asked to show itself on the screen.
868 \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
871 /*! \fn bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
874 Waits for \a timeout milliseconds or until the \a window is active.
876 Returns true if \c window is active within \a timeout milliseconds, otherwise returns false.
878 \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
881 /*! \fn bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
884 Waits for \a timeout milliseconds or until the \a widget's window is exposed.
885 Returns true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns false.
887 This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
888 time after being asked to show itself on the screen.
890 \sa QTest::qWaitForWindowActive()
893 /*! \fn bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
896 Waits for \a timeout milliseconds or until the \a widget's window is active.
898 Returns true if \c widget's window is active within \a timeout milliseconds, otherwise returns false.
900 \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
903 /*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
907 Waits for \a timeout milliseconds or until the \a widget's window is exposed.
908 Returns true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns false.
910 This function does the same as qWaitForWindowExposed().
913 \snippet code/src_qtestlib_qtestcase.cpp 24
915 \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
919 \class QTest::QTouchEventSequence
923 \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
925 To simulate a sequence of touch events on a specific device for a window or widget, call
926 QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
927 the sequence by calling press(), move(), release() and stationary(), and let the
928 instance run out of scope to commit the sequence to the event system.
931 \snippet code/src_qtestlib_qtestcase.cpp 25
935 \fn QTest::QTouchEventSequence::~QTouchEventSequence()
937 Commits this sequence of touch events, unless autoCommit was disabled, and frees allocated resources.
941 \fn void QTest::QTouchEventSequence::commit(bool processEvents)
943 Commits this sequence of touch events to the event system. Normally there is no need to call this
944 function because it is called from the destructor. However, if autoCommit is disabled, the events
945 only get committed upon explicitly calling this function.
947 In special cases tests may want to disable the processing of the events. This can be achieved by
948 setting \a processEvents to false. This results in merely queuing the events, the event loop will
949 not be forced to process them.
953 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWindow *window)
956 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
957 a reference to this QTouchEventSequence.
959 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
960 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
962 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
966 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
968 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
969 a reference to this QTouchEventSequence.
971 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
972 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
974 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
978 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWindow *window)
981 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
982 a reference to this QTouchEventSequence.
984 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
985 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
987 Simulates that the user moved the finger identified by \a touchId.
991 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
993 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
994 a reference to this QTouchEventSequence.
996 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
997 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
999 Simulates that the user moved the finger identified by \a touchId.
1003 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWindow *window)
1006 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
1007 a reference to this QTouchEventSequence.
1009 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
1010 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
1012 Simulates that the user lifted the finger identified by \a touchId.
1016 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
1018 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
1019 a reference to this QTouchEventSequence.
1021 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
1022 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
1024 Simulates that the user lifted the finger identified by \a touchId.
1028 \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
1030 Adds a stationary event for touchpoint \a touchId to this sequence and returns
1031 a reference to this QTouchEventSequence.
1033 Simulates that the user did not move the finger identified by \a touchId.
1037 \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit = true)
1040 Creates and returns a QTouchEventSequence for the \a device to
1041 simulate events for \a window.
1043 When adding touch events to the sequence, \a window will also be used to translate
1044 the position provided to screen coordinates, unless another window is provided in the
1045 respective calls to press(), move() etc.
1047 The touch events are committed to the event system when the destructor of the
1048 QTouchEventSequence is called (ie when the object returned runs out of scope), unless
1049 \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
1054 \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit = true)
1056 Creates and returns a QTouchEventSequence for the \a device to
1057 simulate events for \a widget.
1059 When adding touch events to the sequence, \a widget will also be used to translate
1060 the position provided to screen coordinates, unless another widget is provided in the
1061 respective calls to press(), move() etc.
1063 The touch events are committed to the event system when the destructor of the
1064 QTouchEventSequence is called (ie when the object returned runs out of scope), unless
1065 \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
1069 static bool installCoverageTool(const char * appname, const char * testname)
1071 #ifdef __COVERAGESCANNER__
1072 if (!qEnvironmentVariableIsEmpty("QT_TESTCOCOON_ACTIVE"))
1074 // Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from
1075 // being considered as a stand-alone test regarding the coverage analysis.
1076 qputenv("QT_TESTCOCOON_ACTIVE", "1");
1078 // Install Coverage Tool
1079 __coveragescanner_install(appname);
1080 __coveragescanner_testname(testname);
1081 __coveragescanner_clear();
1092 static QObject *currentTestObject = 0;
1094 class TestFunction {
1096 TestFunction() : function_(-1), data_(0) {}
1097 void set(int function, char *data) { function_ = function; data_ = data; }
1098 char *data() const { return data_; }
1099 int function() const { return function_; }
1100 ~TestFunction() { delete[] data_; }
1106 * Contains the list of test functions that was supplied
1107 * on the command line, if any. Hence, if not empty,
1108 * those functions should be run instead of
1109 * all appearing in the test case.
1111 static TestFunction * testFuncs = 0;
1112 static int testFuncCount = 0;
1114 /** Don't leak testFuncs on exit even on error */
1115 static struct TestFuncCleanup
1124 ~TestFuncCleanup() { cleanup(); }
1127 static int keyDelay = -1;
1128 static int mouseDelay = -1;
1129 static int eventDelay = -1;
1130 #if defined(Q_OS_UNIX)
1131 static bool noCrashHandler = false;
1135 Invoke a method of the object without generating warning if the method does not exist
1137 static void invokeMethod(QObject *obj, const char *methodName)
1139 const QMetaObject *metaObject = obj->metaObject();
1140 int funcIndex = metaObject->indexOfMethod(methodName);
1141 if (funcIndex >= 0) {
1142 QMetaMethod method = metaObject->method(funcIndex);
1143 method.invoke(obj, Qt::DirectConnection);
1147 int defaultEventDelay()
1149 if (eventDelay == -1) {
1150 const QByteArray env = qgetenv("QTEST_EVENT_DELAY");
1152 eventDelay = atoi(env.constData());
1159 int Q_TESTLIB_EXPORT defaultMouseDelay()
1161 if (mouseDelay == -1) {
1162 const QByteArray env = qgetenv("QTEST_MOUSEEVENT_DELAY");
1164 mouseDelay = atoi(env.constData());
1166 mouseDelay = defaultEventDelay();
1171 int Q_TESTLIB_EXPORT defaultKeyDelay()
1173 if (keyDelay == -1) {
1174 const QByteArray env = qgetenv("QTEST_KEYEVENT_DELAY");
1176 keyDelay = atoi(env.constData());
1178 keyDelay = defaultEventDelay();
1183 static bool isValidSlot(const QMetaMethod &sl)
1185 if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0
1186 || sl.returnType() != QMetaType::Void || sl.methodType() != QMetaMethod::Slot)
1188 QByteArray name = sl.name();
1191 if (name.endsWith("_data"))
1193 if (name == "initTestCase" || name == "cleanupTestCase"
1194 || name == "cleanup" || name == "init")
1199 Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
1200 Q_TESTLIB_EXPORT QStringList testFunctions;
1201 Q_TESTLIB_EXPORT QStringList testTags;
1203 static void qPrintTestSlots(FILE *stream, const char *filter = 0)
1205 for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
1206 QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
1207 if (isValidSlot(sl)) {
1208 const QByteArray signature = sl.methodSignature();
1209 if (!filter || QString::fromLatin1(signature).contains(QLatin1String(filter), Qt::CaseInsensitive))
1210 fprintf(stream, "%s\n", signature.constData());
1215 static void qPrintDataTags(FILE *stream)
1217 // Avoid invoking the actual test functions, and also avoid printing irrelevant output:
1218 QTestLog::setPrintAvailableTagsMode();
1220 // Get global data tags:
1221 QTestTable::globalTestTable();
1222 invokeMethod(QTest::currentTestObject, "initTestCase_data()");
1223 const QTestTable *gTable = QTestTable::globalTestTable();
1225 const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject();
1227 // Process test functions:
1228 for (int i = 0; i < currTestMetaObj->methodCount(); ++i) {
1229 QMetaMethod tf = currTestMetaObj->method(i);
1231 if (isValidSlot(tf)) {
1233 // Retrieve local tags:
1234 QStringList localTags;
1236 char *slot = qstrdup(tf.methodSignature().constData());
1237 slot[strlen(slot) - 2] = '\0';
1239 member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
1240 qsnprintf(member.data(), member.size(), "%s_data()", slot);
1241 invokeMethod(QTest::currentTestObject, member.constData());
1242 for (int j = 0; j < table.dataCount(); ++j)
1243 localTags << QLatin1String(table.testData(j)->dataTag());
1245 // Print all tag combinations:
1246 if (gTable->dataCount() == 0) {
1247 if (localTags.count() == 0) {
1248 // No tags at all, so just print the test function:
1249 fprintf(stream, "%s %s\n", currTestMetaObj->className(), slot);
1251 // Only local tags, so print each of them:
1252 for (int k = 0; k < localTags.size(); ++k)
1254 stream, "%s %s %s\n",
1255 currTestMetaObj->className(), slot, localTags.at(k).toLatin1().data());
1258 for (int j = 0; j < gTable->dataCount(); ++j) {
1259 if (localTags.count() == 0) {
1260 // Only global tags, so print the current one:
1262 stream, "%s %s __global__ %s\n",
1263 currTestMetaObj->className(), slot, gTable->testData(j)->dataTag());
1265 // Local and global tags, so print each of the local ones and
1266 // the current global one:
1267 for (int k = 0; k < localTags.size(); ++k)
1269 stream, "%s %s %s __global__ %s\n", currTestMetaObj->className(), slot,
1270 localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag());
1280 static int qToInt(char *str)
1283 int l = (int)strtol(str, &pEnd, 10);
1285 fprintf(stderr, "Invalid numeric parameter: '%s'\n", str);
1291 Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
1293 QTestLog::LogMode logFormat = QTestLog::Plain;
1294 const char *logFilename = 0;
1296 const char *testOptions =
1297 " New-style logging options:\n"
1298 " -o filename,format : Output results to file in the specified format\n"
1299 " Use - to output to stdout\n"
1300 " Valid formats are:\n"
1301 " txt : Plain text\n"
1302 " xunitxml : XML XUnit document\n"
1303 " xml : XML document\n"
1304 " lightxml : A stream of XML tags\n"
1306 " *** Multiple loggers can be specified, but at most one can log to stdout.\n"
1308 " Old-style logging options:\n"
1309 " -o filename : Write the output into file\n"
1310 " -txt : Output results in Plain Text\n"
1311 " -xunitxml : Output results as XML XUnit document\n"
1312 " -xml : Output results as XML document\n"
1313 " -lightxml : Output results as stream of XML tags\n"
1315 " *** If no output file is specified, stdout is assumed.\n"
1316 " *** If no output format is specified, -txt is assumed.\n"
1318 " Test log detail options:\n"
1319 " -silent : Log failures and fatal errors only\n"
1320 " -v1 : Log the start of each testfunction\n"
1321 " -v2 : Log each QVERIFY/QCOMPARE/QTEST (implies -v1)\n"
1322 " -vs : Log every signal emission and resulting slot invocations\n"
1324 " *** The -silent and -v1 options only affect plain text output.\n"
1326 " Testing options:\n"
1327 " -functions : Returns a list of current testfunctions\n"
1328 " -datatags : Returns a list of current data tags.\n"
1329 " A global data tag is preceded by ' __global__ '.\n"
1330 " -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
1331 " -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
1332 " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
1333 " -maxwarnings n : Sets the maximum amount of messages to output.\n"
1334 " 0 means unlimited, default: 2000\n"
1335 #if defined(Q_OS_UNIX)
1336 " -nocrashhandler : Disables the crash handler\n"
1339 " Benchmarking options:\n"
1340 #ifdef QTESTLIB_USE_VALGRIND
1341 " -callgrind : Use callgrind to time benchmarks\n"
1343 #ifdef HAVE_TICK_COUNTER
1344 " -tickcounter : Use CPU tick counters to time benchmarks\n"
1346 " -eventcounter : Counts events received during benchmarks\n"
1347 " -minimumvalue n : Sets the minimum acceptable measurement value\n"
1348 " -iterations n : Sets the number of accumulation iterations.\n"
1349 " -median n : Sets the number of median iterations.\n"
1350 " -vb : Print out verbose benchmarking information.\n";
1352 for (int i = 1; i < argc; ++i) {
1353 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0
1354 || strcmp(argv[i], "/?") == 0) {
1355 printf(" Usage: %s [options] [testfunction[:testdata]]...\n"
1356 " By default, all testfunctions will be run.\n\n"
1357 "%s", argv[0], testOptions);
1361 " QmlTest options:\n"
1362 " -import dir : Specify an import directory.\n"
1363 " -input dir/file : Specify the root directory for test cases or a single test case file.\n"
1364 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1365 " -translation file : Specify the translation file.\n"
1370 " -help : This help\n");
1372 } else if (strcmp(argv[i], "-functions") == 0) {
1374 QTest::printAvailableFunctions = true;
1376 qPrintTestSlots(stdout);
1379 } else if (strcmp(argv[i], "-datatags") == 0) {
1381 qPrintDataTags(stdout);
1384 } else if (strcmp(argv[i], "-txt") == 0) {
1385 logFormat = QTestLog::Plain;
1386 } else if (strcmp(argv[i], "-xunitxml") == 0) {
1387 logFormat = QTestLog::XunitXML;
1388 } else if (strcmp(argv[i], "-xml") == 0) {
1389 logFormat = QTestLog::XML;
1390 } else if (strcmp(argv[i], "-lightxml") == 0) {
1391 logFormat = QTestLog::LightXML;
1392 } else if (strcmp(argv[i], "-silent") == 0) {
1393 QTestLog::setVerboseLevel(-1);
1394 } else if (strcmp(argv[i], "-v1") == 0) {
1395 QTestLog::setVerboseLevel(1);
1396 } else if (strcmp(argv[i], "-v2") == 0) {
1397 QTestLog::setVerboseLevel(2);
1398 } else if (strcmp(argv[i], "-vs") == 0) {
1399 QSignalDumper::startDump();
1400 } else if (strcmp(argv[i], "-o") == 0) {
1401 if (i + 1 >= argc) {
1402 fprintf(stderr, "-o needs an extra parameter specifying the filename and optional format\n");
1406 // Do we have the old or new style -o option?
1407 char *filename = new char[strlen(argv[i])+1];
1408 char *format = new char[strlen(argv[i])+1];
1409 if (sscanf(argv[i], "%[^,],%s", filename, format) == 1) {
1411 logFilename = argv[i];
1414 if (strcmp(format, "txt") == 0)
1415 logFormat = QTestLog::Plain;
1416 else if (strcmp(format, "lightxml") == 0)
1417 logFormat = QTestLog::LightXML;
1418 else if (strcmp(format, "xml") == 0)
1419 logFormat = QTestLog::XML;
1420 else if (strcmp(format, "xunitxml") == 0)
1421 logFormat = QTestLog::XunitXML;
1423 fprintf(stderr, "output format must be one of txt, lightxml, xml or xunitxml\n");
1426 if (strcmp(filename, "-") == 0 && QTestLog::loggerUsingStdout()) {
1427 fprintf(stderr, "only one logger can log to stdout\n");
1430 QTestLog::addLogger(logFormat, filename);
1434 } else if (strcmp(argv[i], "-eventdelay") == 0) {
1435 if (i + 1 >= argc) {
1436 fprintf(stderr, "-eventdelay needs an extra parameter to indicate the delay(ms)\n");
1439 QTest::eventDelay = qToInt(argv[++i]);
1441 } else if (strcmp(argv[i], "-keydelay") == 0) {
1442 if (i + 1 >= argc) {
1443 fprintf(stderr, "-keydelay needs an extra parameter to indicate the delay(ms)\n");
1446 QTest::keyDelay = qToInt(argv[++i]);
1448 } else if (strcmp(argv[i], "-mousedelay") == 0) {
1449 if (i + 1 >= argc) {
1450 fprintf(stderr, "-mousedelay needs an extra parameter to indicate the delay(ms)\n");
1453 QTest::mouseDelay = qToInt(argv[++i]);
1455 } else if (strcmp(argv[i], "-maxwarnings") == 0) {
1456 if (i + 1 >= argc) {
1457 fprintf(stderr, "-maxwarnings needs an extra parameter with the amount of warnings\n");
1460 QTestLog::setMaxWarnings(qToInt(argv[++i]));
1462 #if defined(Q_OS_UNIX)
1463 } else if (strcmp(argv[i], "-nocrashhandler") == 0) {
1464 QTest::noCrashHandler = true;
1466 #ifdef QTESTLIB_USE_VALGRIND
1467 } else if (strcmp(argv[i], "-callgrind") == 0) {
1468 if (QBenchmarkValgrindUtils::haveValgrind())
1469 if (QFileInfo(QDir::currentPath()).isWritable()) {
1470 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindParentProcess);
1472 fprintf(stderr, "WARNING: Current directory not writable. Using the walltime measurer.\n");
1475 fprintf(stderr, "WARNING: Valgrind not found or too old. Make sure it is installed and in your path. "
1476 "Using the walltime measurer.\n");
1478 } else if (strcmp(argv[i], "-callgrindchild") == 0) { // "private" option
1479 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindChildProcess);
1480 QBenchmarkGlobalData::current->callgrindOutFileBase =
1481 QBenchmarkValgrindUtils::outFileBase();
1483 #ifdef HAVE_TICK_COUNTER
1484 } else if (strcmp(argv[i], "-tickcounter") == 0) {
1485 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::TickCounter);
1487 } else if (strcmp(argv[i], "-eventcounter") == 0) {
1488 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::EventCounter);
1489 } else if (strcmp(argv[i], "-minimumvalue") == 0) {
1490 if (i + 1 >= argc) {
1491 fprintf(stderr, "-minimumvalue needs an extra parameter to indicate the minimum time(ms)\n");
1494 QBenchmarkGlobalData::current->walltimeMinimum = qToInt(argv[++i]);
1496 } else if (strcmp(argv[i], "-iterations") == 0) {
1497 if (i + 1 >= argc) {
1498 fprintf(stderr, "-iterations needs an extra parameter to indicate the number of iterations\n");
1501 QBenchmarkGlobalData::current->iterationCount = qToInt(argv[++i]);
1503 } else if (strcmp(argv[i], "-median") == 0) {
1504 if (i + 1 >= argc) {
1505 fprintf(stderr, "-median needs an extra parameter to indicate the number of median iterations\n");
1508 QBenchmarkGlobalData::current->medianIterationCount = qToInt(argv[++i]);
1511 } else if (strcmp(argv[i], "-vb") == 0) {
1512 QBenchmarkGlobalData::current->verboseOutput = true;
1513 } else if (argv[i][0] == '-') {
1514 fprintf(stderr, "Unknown option: '%s'\n\n%s", argv[i], testOptions);
1516 fprintf(stderr, "\nqmltest related options:\n"
1517 " -import : Specify an import directory.\n"
1518 " -input : Specify the root directory for test cases.\n"
1519 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1523 fprintf(stderr, "\n"
1524 " -help : This help\n");
1527 // We can't check the availability of test functions until
1528 // we load the QML files. So just store the data for now.
1531 for (offset = 0; *(argv[i]+offset); ++offset) {
1532 if (*(argv[i]+offset) == ':') {
1533 if (*(argv[i]+offset+1) == ':') {
1534 // "::" is used as a test name separator.
1535 // e.g. "ClickTests::test_click:row1".
1544 QTest::testFunctions += QString::fromLatin1(argv[i]);
1545 QTest::testTags += QString();
1547 QTest::testFunctions +=
1548 QString::fromLatin1(argv[i], colon);
1550 QString::fromLatin1(argv[i] + colon + 1);
1553 if (!QTest::testFuncs) {
1554 QTest::testFuncs = new QTest::TestFunction[512];
1558 char buf[512], *data=0;
1560 for (off = 0; *(argv[i]+off); ++off) {
1561 if (*(argv[i]+off) == ':') {
1567 data = qstrdup(argv[i]+colon+1);
1569 qsnprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
1570 qsnprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
1571 int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
1572 if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
1573 fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", buf);
1575 qPrintTestSlots(stderr, buf);
1576 fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", argv[0]);
1579 testFuncs[testFuncCount].set(idx, data);
1581 QTEST_ASSERT(QTest::testFuncCount < 512);
1585 bool installedTestCoverage = installCoverageTool(QTestResult::currentAppname(), QTestResult::currentTestObjectName());
1586 QTestLog::setInstalledTestCoverage(installedTestCoverage);
1588 // If no loggers were created by the long version of the -o command-line
1589 // option, create a logger using whatever filename and format were
1590 // set using the old-style command-line options.
1591 if (QTestLog::loggerCount() == 0)
1592 QTestLog::addLogger(logFormat, logFilename);
1595 QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
1597 const int count = container.count();
1599 return QBenchmarkResult();
1602 return container.at(0);
1604 QList<QBenchmarkResult> containerCopy = container;
1605 qSort(containerCopy);
1607 const int middle = count / 2;
1609 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
1610 return containerCopy.at(middle);
1613 struct QTestDataSetter
1615 QTestDataSetter(QTestData *data)
1617 QTestResult::setCurrentTestData(data);
1621 QTestResult::setCurrentTestData(0);
1625 static void qInvokeTestMethodDataEntry(char *slot)
1627 /* Benchmarking: for each median iteration*/
1629 bool isBenchmark = false;
1630 int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
1632 QList<QBenchmarkResult> results;
1634 QBenchmarkTestMethodData::current->beginDataRun();
1636 /* Benchmarking: for each accumulation iteration*/
1639 invokeMethod(QTest::currentTestObject, "init()");
1640 if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed())
1643 QBenchmarkTestMethodData::current->result = QBenchmarkResult();
1644 QBenchmarkTestMethodData::current->resultAccepted = false;
1646 QBenchmarkGlobalData::current->context.tag =
1648 QTestResult::currentDataTag()
1649 ? QTestResult::currentDataTag() : "");
1651 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
1652 Qt::DirectConnection);
1654 QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
1656 isBenchmark = QBenchmarkTestMethodData::current->isBenchmark();
1658 QTestResult::finishedCurrentTestData();
1660 invokeMethod(QTest::currentTestObject, "cleanup()");
1662 // If the test isn't a benchmark, finalize the result after cleanup() has finished.
1664 QTestResult::finishedCurrentTestDataCleanup();
1666 // If this test method has a benchmark, repeat until all measurements are
1668 // The QBENCHMARK macro increases the number of iterations for each run until
1670 } while (invokeOk && isBenchmark
1671 && QBenchmarkTestMethodData::current->resultsAccepted() == false
1672 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1674 QBenchmarkTestMethodData::current->endDataRun();
1675 if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) {
1676 if (i > -1) // iteration -1 is the warmup iteration.
1677 results.append(QBenchmarkTestMethodData::current->result);
1679 if (isBenchmark && QBenchmarkGlobalData::current->verboseOutput) {
1681 QTestLog::info(qPrintable(
1682 QString::fromLatin1("warmup stage result : %1")
1683 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1685 QTestLog::info(qPrintable(
1686 QString::fromLatin1("accumulation stage result: %1")
1687 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1691 } while (isBenchmark
1692 && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount())
1693 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1695 // If the test is a benchmark, finalize the result after all iterations have finished.
1697 bool testPassed = !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed();
1698 QTestResult::finishedCurrentTestDataCleanup();
1699 // Only report benchmark figures if the test passed
1700 if (testPassed && QBenchmarkTestMethodData::current->resultsAccepted())
1701 QTestLog::addBenchmarkResult(qMedian(results));
1708 Call slot_data(), init(), slot(), cleanup(), init(), slot(), cleanup(), ...
1709 If data is set then it is the only test that is performed
1711 If the function was successfully called, true is returned, otherwise
1714 static bool qInvokeTestMethod(const char *slotName, const char *data=0)
1716 QTEST_ASSERT(slotName);
1718 QBenchmarkTestMethodData benchmarkData;
1719 QBenchmarkTestMethodData::current = &benchmarkData;
1721 QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
1726 char *slot = qstrdup(slotName);
1727 slot[strlen(slot) - 2] = '\0';
1728 QTestResult::setCurrentTestFunction(slot);
1730 const QTestTable *gTable = QTestTable::globalTestTable();
1731 const int globalDataCount = gTable->dataCount();
1732 int curGlobalDataIndex = 0;
1734 /* For each test function that has a *_data() table/function, do: */
1736 if (!gTable->isEmpty())
1737 QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
1739 if (curGlobalDataIndex == 0) {
1740 qsnprintf(member, 512, "%s_data()", slot);
1741 invokeMethod(QTest::currentTestObject, member);
1744 bool foundFunction = false;
1745 if (!QTestResult::skipCurrentTest()) {
1746 int curDataIndex = 0;
1747 const int dataCount = table.dataCount();
1749 // Data tag requested but none available?
1750 if (data && !dataCount) {
1751 // Let empty data tag through.
1755 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1756 fprintf(stderr, "Function has no testdata.\n");
1761 /* For each entry in the data table, do: */
1763 QTestResult::setSkipCurrentTest(false);
1764 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
1765 foundFunction = true;
1766 QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
1767 : table.testData(curDataIndex));
1769 qInvokeTestMethodDataEntry(slot);
1775 } while (curDataIndex < dataCount);
1778 if (data && !foundFunction) {
1779 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1780 fprintf(stderr, "Available testdata:\n");
1781 for (int i = 0; i < table.dataCount(); ++i)
1782 fprintf(stderr, "%s\n", table.testData(i)->dataTag());
1786 QTestResult::setCurrentGlobalTestData(0);
1787 ++curGlobalDataIndex;
1788 } while (curGlobalDataIndex < globalDataCount);
1790 QTestResult::finishedCurrentTestFunction();
1791 QTestResult::setSkipCurrentTest(false);
1792 QTestResult::setCurrentTestData(0);
1798 void *fetchData(QTestData *data, const char *tagName, int typeId)
1800 QTEST_ASSERT(typeId);
1801 QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");
1802 QTEST_ASSERT(data->parent());
1804 int idx = data->parent()->indexOf(tagName);
1806 if (idx == -1 || idx >= data->dataCount()) {
1807 qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
1811 if (typeId != data->parent()->elementTypeId(idx)) {
1812 qFatal("Requested type '%s' does not match available type '%s'.",
1813 QMetaType::typeName(typeId),
1814 QMetaType::typeName(data->parent()->elementTypeId(idx)));
1817 return data->data(idx);
1821 \fn char* QTest::toHexRepresentation(const char *ba, int length)
1823 Returns a pointer to a string that is the string \a ba represented
1824 as a space-separated sequence of hex characters. If the input is
1825 considered too long, it is truncated. A trucation is indicated in
1826 the returned string as an ellipsis at the end.
1828 \a length is the length of the string \a ba.
1830 char *toHexRepresentation(const char *ba, int length)
1835 /* We output at maximum about maxLen characters in order to avoid
1836 * running out of memory and flooding things when the byte array
1839 * maxLen can't be for example 200 because QTestLib is sprinkled with fixed
1842 const int maxLen = 50;
1843 const int len = qMin(maxLen, length);
1846 if (length > maxLen) {
1847 const int size = len * 3 + 4;
1848 result = new char[size];
1850 char *const forElipsis = result + size - 5;
1851 forElipsis[0] = ' ';
1852 forElipsis[1] = '.';
1853 forElipsis[2] = '.';
1854 forElipsis[3] = '.';
1855 result[size - 1] = '\0';
1858 const int size = len * 3;
1859 result = new char[size];
1860 result[size - 1] = '\0';
1863 const char toHex[] = "0123456789ABCDEF";
1868 const char at = ba[i];
1870 result[o] = toHex[(at >> 4) & 0x0F];
1872 result[o] = toHex[at & 0x0F];
1887 static void qInvokeTestMethods(QObject *testObject)
1889 const QMetaObject *metaObject = testObject->metaObject();
1890 QTEST_ASSERT(metaObject);
1891 QTestLog::startLogging();
1892 QTestResult::setCurrentTestFunction("initTestCase");
1893 QTestTable::globalTestTable();
1894 invokeMethod(testObject, "initTestCase_data()");
1896 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
1897 invokeMethod(testObject, "initTestCase()");
1899 // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy.
1900 const bool previousFailed = QTestResult::currentTestFailed();
1901 QTestResult::finishedCurrentTestData();
1902 QTestResult::finishedCurrentTestDataCleanup();
1903 QTestResult::finishedCurrentTestFunction();
1905 if (!QTestResult::skipCurrentTest() && !previousFailed) {
1907 if (QTest::testFuncs) {
1908 for (int i = 0; i != QTest::testFuncCount; i++) {
1909 if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).methodSignature().constData(),
1910 QTest::testFuncs[i].data())) {
1914 testFuncCleaner.cleanup();
1916 int methodCount = metaObject->methodCount();
1917 QMetaMethod *testMethods = new QMetaMethod[methodCount];
1918 for (int i = 0; i != methodCount; i++)
1919 testMethods[i] = metaObject->method(i);
1920 for (int i = 0; i != methodCount; i++) {
1921 if (!isValidSlot(testMethods[i]))
1923 if (!qInvokeTestMethod(testMethods[i].methodSignature().constData()))
1926 delete[] testMethods;
1931 QTestResult::setSkipCurrentTest(false);
1932 QTestResult::setCurrentTestFunction("cleanupTestCase");
1933 invokeMethod(testObject, "cleanupTestCase()");
1934 QTestResult::finishedCurrentTestData();
1935 QTestResult::finishedCurrentTestDataCleanup();
1937 QTestResult::finishedCurrentTestFunction();
1938 QTestResult::setCurrentTestFunction(0);
1939 QTestTable::clearGlobalTestTable();
1941 QTestLog::stopLogging();
1944 #if defined(Q_OS_UNIX)
1945 class FatalSignalHandler
1948 FatalSignalHandler();
1949 ~FatalSignalHandler();
1952 static void signal(int);
1953 sigset_t handledSignals;
1956 void FatalSignalHandler::signal(int signum)
1958 qFatal("Received signal %d", signum);
1959 #if defined(Q_OS_INTEGRITY)
1961 struct sigaction act;
1962 memset(&act, 0, sizeof(struct sigaction));
1963 act.sa_handler = SIG_DFL;
1964 sigaction(signum, &act, NULL);
1969 FatalSignalHandler::FatalSignalHandler()
1971 sigemptyset(&handledSignals);
1973 const int fatalSignals[] = {
1974 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 };
1976 struct sigaction act;
1977 memset(&act, 0, sizeof(act));
1978 act.sa_handler = FatalSignalHandler::signal;
1980 // Remove the handler after it is invoked.
1981 #if !defined(Q_OS_INTEGRITY)
1982 act.sa_flags = SA_RESETHAND;
1984 // Block all fatal signals in our signal handler so we don't try to close
1985 // the testlog twice.
1986 sigemptyset(&act.sa_mask);
1987 for (int i = 0; fatalSignals[i]; ++i)
1988 sigaddset(&act.sa_mask, fatalSignals[i]);
1990 struct sigaction oldact;
1992 for (int i = 0; fatalSignals[i]; ++i) {
1993 sigaction(fatalSignals[i], &act, &oldact);
1996 oldact.sa_flags & SA_SIGINFO ||
1998 oldact.sa_handler != SIG_DFL) {
1999 sigaction(fatalSignals[i], &oldact, 0);
2002 sigaddset(&handledSignals, fatalSignals[i]);
2008 FatalSignalHandler::~FatalSignalHandler()
2010 // Unregister any of our remaining signal handlers
2011 struct sigaction act;
2012 memset(&act, 0, sizeof(act));
2013 act.sa_handler = SIG_DFL;
2015 struct sigaction oldact;
2017 for (int i = 1; i < 32; ++i) {
2018 if (!sigismember(&handledSignals, i))
2020 sigaction(i, &act, &oldact);
2022 // If someone overwrote it in the mean time, put it back
2023 if (oldact.sa_handler != FatalSignalHandler::signal)
2024 sigaction(i, &oldact, 0);
2034 Executes tests declared in \a testObject. In addition, the private slots
2035 \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
2036 are executed if they exist. See \l{Creating a Test} for more details.
2038 Optionally, the command line arguments \a argc and \a argv can be provided.
2039 For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.
2041 The following example will run all tests in \c MyTestObject:
2043 \snippet code/src_qtestlib_qtestcase.cpp 18
2045 This function returns 0 if no tests failed, or a value other than 0 if one
2046 or more tests failed or in case of unhandled exceptions. (Skipped tests do
2047 not influence the return value.)
2049 For stand-alone test applications, the convenience macro \l QTEST_MAIN() can
2050 be used to declare a main() function that parses the command line arguments
2051 and executes the tests, avoiding the need to call this function explicitly.
2053 The return value from this function is also the exit code of the test
2054 application when the \l QTEST_MAIN() macro is used.
2056 For stand-alone test applications, this function should not be called more
2057 than once, as command-line options for logging test output to files and
2058 executing individual test functions will not behave correctly.
2060 Note: This function is not reentrant, only one test can run at a time. A
2061 test that was executed with qExec() can't run another test via qExec() and
2062 threads are not allowed to call qExec() simultaneously.
2064 If you have programatically created the arguments, as opposed to getting them
2065 from the arguments in \c main(), it is likely of interest to use
2066 QTest::qExec(QObject *, const QStringList &) since it is Unicode safe.
2071 int QTest::qExec(QObject *testObject, int argc, char **argv)
2073 QBenchmarkGlobalData benchmarkData;
2074 QBenchmarkGlobalData::current = &benchmarkData;
2076 #ifdef QTESTLIB_USE_VALGRIND
2077 int callgrindChildExitCode = 0;
2081 bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
2082 IOPMAssertionID powerID;
2084 #ifndef QT_NO_EXCEPTIONS
2088 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2089 # if !defined(Q_CC_MINGW)
2090 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
2092 SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
2096 if (macNeedsActivate) {
2097 CFStringRef reasonForActivity= CFSTR("No Display Sleep");
2098 IOReturn ok = IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, reasonForActivity, &powerID);
2100 if (ok != kIOReturnSuccess)
2101 macNeedsActivate = false; // no need to release the assertion on exit.
2105 QTestResult::reset();
2107 QTEST_ASSERT(testObject);
2108 QTEST_ASSERT(!currentTestObject);
2109 currentTestObject = testObject;
2111 const QMetaObject *metaObject = testObject->metaObject();
2112 QTEST_ASSERT(metaObject);
2114 QTestResult::setCurrentTestObject(metaObject->className());
2116 QTestResult::setCurrentAppname(argv[0]);
2118 qtest_qParseArgs(argc, argv, false);
2120 #ifdef QTESTLIB_USE_VALGRIND
2121 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
2122 const QStringList origAppArgs(QCoreApplication::arguments());
2123 if (!QBenchmarkValgrindUtils::rerunThroughCallgrind(origAppArgs, callgrindChildExitCode))
2126 QBenchmarkValgrindUtils::cleanup();
2131 #if defined(Q_OS_UNIX)
2132 QScopedPointer<FatalSignalHandler> handler;
2133 if (!noCrashHandler)
2134 handler.reset(new FatalSignalHandler);
2136 qInvokeTestMethods(testObject);
2139 #ifndef QT_NO_EXCEPTIONS
2141 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
2142 if (QTestResult::currentTestFunction()) {
2143 QTestResult::finishedCurrentTestFunction();
2144 QTestResult::setCurrentTestFunction(0);
2147 QTestLog::stopLogging();
2149 if (macNeedsActivate) {
2150 IOPMAssertionRelease(powerID);
2153 currentTestObject = 0;
2155 // Rethrow exception to make debugging easier.
2161 currentTestObject = 0;
2163 QSignalDumper::endDump();
2166 if (macNeedsActivate) {
2167 IOPMAssertionRelease(powerID);
2171 #ifdef QTESTLIB_USE_VALGRIND
2172 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
2173 return callgrindChildExitCode;
2175 // make sure our exit code is never going above 127
2176 // since that could wrap and indicate 0 test fails
2177 return qMin(QTestLog::failCount(), 127);
2184 Behaves identically to qExec(QObject *, int, char**) but takes a
2185 QStringList of \a arguments instead of a \c char** list.
2187 int QTest::qExec(QObject *testObject, const QStringList &arguments)
2189 const int argc = arguments.count();
2190 QVarLengthArray<char *> argv(argc);
2192 QVector<QByteArray> args;
2195 for (int i = 0; i < argc; ++i)
2197 args.append(arguments.at(i).toLocal8Bit().constData());
2198 argv[i] = args.last().data();
2201 return qExec(testObject, argc, argv.data());
2206 void QTest::qFail(const char *statementStr, const char *file, int line)
2208 QTestResult::addFailure(statementStr, file, line);
2213 bool QTest::qVerify(bool statement, const char *statementStr, const char *description,
2214 const char *file, int line)
2216 return QTestResult::verify(statement, statementStr, description, file, line);
2219 /*! \fn void QTest::qSkip(const char *message, const char *file, int line)
2222 void QTest::qSkip(const char *message, const char *file, int line)
2224 QTestResult::addSkip(message, file, line);
2225 QTestResult::setSkipCurrentTest(true);
2228 /*! \fn bool QTest::qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line)
2231 bool QTest::qExpectFail(const char *dataIndex, const char *comment,
2232 QTest::TestFailMode mode, const char *file, int line)
2234 return QTestResult::expectFail(dataIndex, qstrdup(comment), mode, file, line);
2239 void QTest::qWarn(const char *message, const char *file, int line)
2241 QTestLog::warn(message, file, line);
2245 Ignores messages created by qDebug() or qWarning(). If the \a message
2246 with the corresponding \a type is outputted, it will be removed from the
2247 test log. If the test finished and the \a message was not outputted,
2248 a test failure is appended to the test log.
2250 \b {Note:} Invoking this function will only ignore one message.
2251 If the message you want to ignore is outputted twice, you have to
2252 call ignoreMessage() twice, too.
2255 \snippet code/src_qtestlib_qtestcase.cpp 19
2257 The example above tests that QDir::mkdir() outputs the right warning when invoked
2258 with an invalid file name.
2260 void QTest::ignoreMessage(QtMsgType type, const char *message)
2262 QTestLog::ignoreMessage(type, message);
2269 static inline bool isWindowsBuildDirectory(const QString &dirName)
2271 return dirName.compare(QStringLiteral("Debug"), Qt::CaseInsensitive) == 0
2272 || dirName.compare(QStringLiteral("Release"), Qt::CaseInsensitive) == 0;
2276 QString QTest::qFindTestData(const QString& base, const char *file, int line, const char *builddir)
2280 // Testdata priorities:
2282 // 1. relative to test binary.
2284 QDir binDirectory(QCoreApplication::applicationDirPath());
2285 if (binDirectory.exists(base)) {
2286 found = binDirectory.absoluteFilePath(base);
2289 // Windows: The executable is typically located in one of the
2290 // 'Release' or 'Debug' directories.
2291 else if (isWindowsBuildDirectory(binDirectory.dirName())
2292 && binDirectory.cdUp() && binDirectory.exists(base)) {
2293 found = binDirectory.absoluteFilePath(base);
2296 else if (QTestLog::verboseLevel() >= 2) {
2297 const QString candidate = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + QLatin1Char('/') + base);
2298 QTestLog::info(qPrintable(
2299 QString::fromLatin1("testdata %1 not found relative to test binary [%2]; "
2300 "checking next location").arg(base, candidate)),
2305 // 2. installed path.
2306 if (found.isEmpty()) {
2307 const char *testObjectName = QTestResult::currentTestObjectName();
2308 if (testObjectName) {
2309 QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
2310 QString candidate = QString::fromLatin1("%1/%2/%3")
2311 .arg(testsPath, QFile::decodeName(testObjectName).toLower(), base);
2312 if (QFileInfo(candidate).exists()) {
2315 else if (QTestLog::verboseLevel() >= 2) {
2316 QTestLog::info(qPrintable(
2317 QString::fromLatin1("testdata %1 not found in tests install path [%2]; "
2318 "checking next location")
2319 .arg(base, QDir::toNativeSeparators(candidate))),
2325 // 3. relative to test source.
2326 if (found.isEmpty()) {
2327 // srcdir is the directory containing the calling source file.
2328 QFileInfo srcdir = QFileInfo(QFile::decodeName(file)).path();
2330 // If the srcdir is relative, that means it is relative to the current working
2331 // directory of the compiler at compile time, which should be passed in as `builddir'.
2332 if (!srcdir.isAbsolute() && builddir) {
2333 srcdir.setFile(QFile::decodeName(builddir) + QLatin1String("/") + srcdir.filePath());
2336 QString candidate = QString::fromLatin1("%1/%2").arg(srcdir.canonicalFilePath(), base);
2337 if (QFileInfo(candidate).exists()) {
2340 else if (QTestLog::verboseLevel() >= 2) {
2341 QTestLog::info(qPrintable(
2342 QString::fromLatin1("testdata %1 not found relative to source path [%2]")
2343 .arg(base, QDir::toNativeSeparators(candidate))),
2348 if (found.isEmpty()) {
2349 QTest::qWarn(qPrintable(
2350 QString::fromLatin1("testdata %1 could not be located!").arg(base)),
2353 else if (QTestLog::verboseLevel() >= 1) {
2354 QTestLog::info(qPrintable(
2355 QString::fromLatin1("testdata %1 was located at %2").arg(base, QDir::toNativeSeparators(found))),
2364 QString QTest::qFindTestData(const char *base, const char *file, int line, const char *builddir)
2366 return qFindTestData(QFile::decodeName(base), file, line, builddir);
2371 void *QTest::qData(const char *tagName, int typeId)
2373 return fetchData(QTestResult::currentTestData(), tagName, typeId);
2378 void *QTest::qGlobalData(const char *tagName, int typeId)
2380 return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
2385 void *QTest::qElementData(const char *tagName, int metaTypeId)
2387 QTEST_ASSERT(tagName);
2388 QTestData *data = QTestResult::currentTestData();
2390 QTEST_ASSERT(data->parent());
2392 int idx = data->parent()->indexOf(tagName);
2393 QTEST_ASSERT(idx != -1);
2394 QTEST_ASSERT(data->parent()->elementTypeId(idx) == metaTypeId);
2396 return data->data(data->parent()->indexOf(tagName));
2401 void QTest::addColumnInternal(int id, const char *name)
2403 QTestTable *tbl = QTestTable::currentTestTable();
2404 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
2406 tbl->addColumn(id, name);
2410 Appends a new row to the current test data. \a dataTag is the name of
2411 the testdata that will appear in the test output. Returns a QTestData reference
2412 that can be used to stream in data.
2415 \snippet code/src_qtestlib_qtestcase.cpp 20
2417 \b {Note:} This macro can only be used in a test's data function
2418 that is invoked by the test framework.
2420 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2421 a more extensive example.
2423 \sa addColumn(), QFETCH()
2425 QTestData &QTest::newRow(const char *dataTag)
2427 QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null");
2428 QTestTable *tbl = QTestTable::currentTestTable();
2429 QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot.");
2430 QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows.");
2432 return *tbl->newData(dataTag);
2435 /*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
2437 Adds a column with type \c{T} to the current test data.
2438 \a name is the name of the column. \a dummy is a workaround
2439 for buggy compilers and can be ignored.
2441 To populate the column with values, newRow() can be used. Use
2442 \l QFETCH() to fetch the data in the actual test.
2445 \snippet code/src_qtestlib_qtestcase.cpp 21
2447 To add custom types to the testdata, the type must be registered with
2448 QMetaType via \l Q_DECLARE_METATYPE().
2450 \b {Note:} This macro can only be used in a test's data function
2451 that is invoked by the test framework.
2453 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2454 a more extensive example.
2456 \sa QTest::newRow(), QFETCH(), QMetaType
2460 Returns the name of the test function that is currently executed.
2464 \snippet code/src_qtestlib_qtestcase.cpp 22
2466 const char *QTest::currentTestFunction()
2468 return QTestResult::currentTestFunction();
2472 Returns the name of the current test data. If the test doesn't
2473 have any assigned testdata, the function returns 0.
2475 const char *QTest::currentDataTag()
2477 return QTestResult::currentDataTag();
2481 Returns true if the current test function failed, otherwise false.
2483 bool QTest::currentTestFailed()
2485 return QTestResult::currentTestFailed();
2489 Sleeps for \a ms milliseconds, blocking execution of the
2490 test. qSleep() will not do any event processing and leave your test
2491 unresponsive. Network communication might time out while
2492 sleeping. Use \l qWait() to do non-blocking sleeping.
2494 \a ms must be greater than 0.
2496 \b {Note:} The qSleep() function calls either \c nanosleep() on
2497 unix or \c Sleep() on windows, so the accuracy of time spent in
2498 qSleep() depends on the operating system.
2501 \snippet code/src_qtestlib_qtestcase.cpp 23
2505 void QTest::qSleep(int ms)
2507 QTEST_ASSERT(ms > 0);
2512 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
2513 nanosleep(&ts, NULL);
2519 QObject *QTest::testObject()
2521 return currentTestObject;
2525 This function is called by various specializations of QTest::qCompare
2526 to decide whether to report a failure and to produce verbose test output.
2528 The failureMsg parameter can be null, in which case a default message
2529 will be output if the compare fails. If the compare succeeds, failureMsg
2532 If the caller has already passed a failure message showing the compared
2533 values, or if those values cannot be stringified, val1 and val2 can be null.
2535 bool QTest::compare_helper(bool success, const char *failureMsg,
2536 char *val1, char *val2,
2537 const char *actual, const char *expected,
2538 const char *file, int line)
2540 return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
2543 /*! \fn bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
2546 bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected,
2547 const char *file, int line)
2549 return compare_helper(qFuzzyCompare(t1, t2), "Compared floats are not the same (fuzzy compare)",
2550 toString(t1), toString(t2), actual, expected, file, line);
2553 /*! \fn bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
2556 bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected,
2557 const char *file, int line)
2559 return compare_helper(qFuzzyCompare(t1, t2), "Compared doubles are not the same (fuzzy compare)",
2560 toString(t1), toString(t2), actual, expected, file, line);
2563 #define TO_STRING_IMPL(TYPE, FORMAT) \
2564 template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
2566 char *msg = new char[128]; \
2567 qsnprintf(msg, 128, #FORMAT, t); \
2571 TO_STRING_IMPL(short, %hd)
2572 TO_STRING_IMPL(ushort, %hu)
2573 TO_STRING_IMPL(int, %d)
2574 TO_STRING_IMPL(uint, %u)
2575 TO_STRING_IMPL(long, %ld)
2576 TO_STRING_IMPL(ulong, %lu)
2577 #if defined(Q_OS_WIN)
2578 TO_STRING_IMPL(qint64, %I64d)
2579 TO_STRING_IMPL(quint64, %I64u)
2581 TO_STRING_IMPL(qint64, %lld)
2582 TO_STRING_IMPL(quint64, %llu)
2584 TO_STRING_IMPL(bool, %d)
2585 TO_STRING_IMPL(char, %c)
2586 TO_STRING_IMPL(float, %g)
2587 TO_STRING_IMPL(double, %lg)
2591 char *QTest::toString(const char *str)
2595 char *msg = new char[strlen(str) + 1];
2596 return qstrcpy(msg, str);
2601 char *QTest::toString(const void *p)
2603 char *msg = new char[128];
2604 qsnprintf(msg, 128, "%p", p);
2610 bool QTest::compare_string_helper(const char *t1, const char *t2, const char *actual,
2611 const char *expected, const char *file, int line)
2613 return compare_helper(qstrcmp(t1, t2) == 0, "Compared strings are not the same",
2614 toString(t1), toString(t2), actual, expected, file, line);
2617 /*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
2621 /*! \fn bool QTest::qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
2626 /*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
2630 /*! \fn bool QTest::qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line)
2634 /*! \fn bool QTest::qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, const char *file, int line)
2638 /*! \fn bool QTest::qCompare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2642 /*! \fn bool QTest::qCompare(const T *t1, const T *t2, const char *actual, const char *expected, const char *file, int line)
2646 /*! \fn bool QTest::qCompare(T *t1, T *t2, const char *actual, const char *expected, const char *file, int line)
2650 /*! \fn bool QTest::qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected, const char *file, int line)
2654 /*! \fn bool QTest::qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected, const char *file, int line)
2658 /*! \fn bool QTest::qCompare(const char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2662 /*! \fn bool QTest::qCompare(char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2666 /*! \fn bool QTest::qCompare(char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2670 /*! \fn bool QTest::qCompare(const char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2674 /*! \fn bool QTest::qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
2678 /*! \fn bool QTest::qCompare(QLatin1String const &t1, QString const &t2, const char *actual, const char *expected, const char *file, int line)
2682 /*! \fn bool QTest::qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected, const char *file, int line)
2686 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2690 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2694 /*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2698 /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
2702 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, QString text, Qt::KeyboardModifiers modifier, int delay=-1)
2706 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
2710 /*! \fn void QTest::simulateEvent(QWidget *widget, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)