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 <Carbon/Carbon.h> // for SetFrontProcess
87 #include <IOKit/pwr_mgt/IOPMLib.h>
97 \brief The QTest namespace contains all the functions and
98 declarations that are related to the QTestLib tool.
100 Please refer to the \l{QTestLib Manual} documentation for information on
101 how to write unit tests.
104 /*! \macro QVERIFY(condition)
108 The QVERIFY() macro checks whether the \a condition is true or not. If it is
109 true, execution continues. If not, a failure is recorded in the test log
110 and the test won't be executed further.
112 \b {Note:} This macro can only be used in a test function that is invoked
113 by the test framework.
116 \snippet code/src_qtestlib_qtestcase.cpp 0
118 \sa QCOMPARE(), QTRY_VERIFY()
121 /*! \macro QVERIFY2(condition, message)
125 The QVERIFY2() macro behaves exactly like QVERIFY(), except that it outputs
126 a verbose \a message when \a condition is false. The \a message is a plain
130 \snippet code/src_qtestlib_qtestcase.cpp 1
132 \sa QVERIFY(), QCOMPARE()
135 /*! \macro QCOMPARE(actual, expected)
139 The QCOMPARE macro compares an \a actual value to an \a expected value using
140 the equals operator. If \a actual and \a expected are identical, execution
141 continues. If not, a failure is recorded in the test log and the test
142 won't be executed further.
144 In the case of comparing floats and doubles, qFuzzyCompare() is used for
145 comparing. This means that comparing to 0 will likely fail. One solution
146 to this is to compare to 1, and add 1 to the produced output.
148 QCOMPARE tries to output the contents of the values if the comparison fails,
149 so it is visible from the test log why the comparison failed.
151 QCOMPARE is very strict on the data types. Both \a actual and \a expected
152 have to be of the same type, otherwise the test won't compile. This prohibits
153 unspecified behavior from being introduced; that is behavior that usually
154 occurs when the compiler implicitly casts the argument.
156 For your own classes, you can use \l QTest::toString() to format values for
157 outputting into the test log.
159 \note This macro can only be used in a test function that is invoked
160 by the test framework.
163 \snippet code/src_qtestlib_qtestcase.cpp 2
165 \sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
168 /*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
173 The QTRY_VERIFY_WITH_TIMEOUT() macro is similar to QVERIFY(), but checks the \a condition
174 repeatedly, until either the condition becomes true or the \a timeout is
175 reached. Between each evaluation, events will be processed. If the timeout
176 is reached, a failure is recorded in the test log and the test won't be
179 \note This macro can only be used in a test function that is invoked
180 by the test framework.
182 \sa QTRY_VERIFY(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
186 /*! \macro QTRY_VERIFY(condition)
191 Invokes QTRY_VERIFY_WITH_TIMEOUT() with a timeout of five seconds.
193 \note This macro can only be used in a test function that is invoked
194 by the test framework.
196 \sa QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
199 /*! \macro QTRY_COMPARE_WITH_TIMEOUT(actual, expected, timeout)
204 The QTRY_COMPARE_WITH_TIMEOUT() macro is similar to QCOMPARE(), but performs the comparison
205 of the \a actual and \a expected values repeatedly, until either the two values
206 are equal or the \a timeout is reached. Between each comparison, events
207 will be processed. If the timeout is reached, a failure is recorded in the
208 test log and the test won't be executed further.
210 \note This macro can only be used in a test function that is invoked
211 by the test framework.
213 \sa QTRY_COMPARE(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
216 /*! \macro QTRY_COMPARE(actual, expected)
221 Invokes QTRY_COMPARE_WITH_TIMEOUT() with a timeout of five seconds.
223 \note This macro can only be used in a test function that is invoked
224 by the test framework.
226 \sa QTRY_COMPARE_WITH_TIMEOUT(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
229 /*! \macro QFETCH(type, name)
233 The fetch macro creates a local variable named \a name with the type \a type
234 on the stack. \a name has to match the element name from the test's data.
235 If no such element exists, the test will assert.
237 Assuming a test has the following data:
239 \snippet code/src_qtestlib_qtestcase.cpp 3
241 The test data has two elements, a QString called \c aString and an integer
242 called \c expected. To fetch these values in the actual test:
244 \snippet code/src_qtestlib_qtestcase.cpp 4
246 \c aString and \c expected are variables on the stack that are initialized with
247 the current test data.
249 \b {Note:} This macro can only be used in a test function that is invoked
250 by the test framework. The test function must have a _data function.
253 /*! \macro QWARN(message)
258 Appends \a message as a warning to the test log. This macro can be used anywhere
262 /*! \macro QFAIL(message)
266 This macro can be used to force a test failure. The test stops
267 executing and the failure \a message is appended to the test log.
269 \b {Note:} This macro can only be used in a test function that is invoked
270 by the test framework.
274 \snippet code/src_qtestlib_qtestcase.cpp 5
277 /*! \macro QTEST(actual, testElement)
281 QTEST() is a convenience macro for \l QCOMPARE() that compares
282 the value \a actual with the element \a testElement from the test's data.
283 If there is no such element, the test asserts.
285 Apart from that, QTEST() behaves exactly as \l QCOMPARE().
289 \snippet code/src_qtestlib_qtestcase.cpp 6
293 \snippet code/src_qtestlib_qtestcase.cpp 7
298 /*! \macro QSKIP(description)
302 If called from a test function, the QSKIP() macro stops execution of the test
303 without adding a failure to the test log. You can use it to skip tests that
304 wouldn't make sense in the current configuration. The text \a description is
305 appended to the test log and should contain an explanation of why the test
306 couldn't be executed.
308 If the test is data-driven, each call to QSKIP() will skip only the current
309 row of test data, so an unconditional call to QSKIP will produce one skip
310 message in the test log for each row of test data.
312 If called from an _data function, the QSKIP() macro will stop execution of
313 the _data function and will prevent execution of the associated test
316 If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
317 skip all test and _data functions.
319 \b {Note:} This macro can only be used in a test function or _data
320 function that is invoked by the test framework.
323 \snippet code/src_qtestlib_qtestcase.cpp 8
326 /*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
330 The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
331 expected failure. Instead of adding a failure to the test log, an expected
332 failure will be reported.
334 If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
335 but passes instead, an unexpected pass (XPASS) is written to the test log.
337 The parameter \a dataIndex describes for which entry in the test data the
338 failure is expected. Pass an empty string (\c{""}) if the failure
339 is expected for all entries or if no test data exists.
341 \a comment will be appended to the test log for the expected failure.
343 \a mode is a \l QTest::TestFailMode and sets whether the test should
344 continue to execute or not.
346 \b {Note:} This macro can only be used in a test function that is invoked
347 by the test framework.
350 \snippet code/src_qtestlib_qtestcase.cpp 9
352 In the example above, an expected fail will be written into the test output
353 if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
354 is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
355 statement in the example.
358 \snippet code/src_qtestlib_qtestcase.cpp 10
360 The above testfunction will not continue executing for the test data
363 \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
366 /*! \macro QFINDTESTDATA(filename)
371 Returns a QString for the testdata file referred to by \a filename, or an
372 empty QString if the testdata file could not be found.
374 This macro allows the test to load data from an external file without
375 hardcoding an absolute filename into the test, or using relative paths
376 which may be error prone.
378 The returned path will be the first path from the following list which
379 resolves to an existing file or directory:
382 \li \a filename relative to QCoreApplication::applicationDirPath()
383 (only if a QCoreApplication or QApplication object has been created).
384 \li \a filename relative to the test's standard install directory
385 (QLibraryInfo::TestsPath with the lowercased testcase name appended).
386 \li \a filename relative to the directory containing the source file from which
387 QFINDTESTDATA is invoked.
390 If the named file/directory does not exist at any of these locations,
391 a warning is printed to the test log.
393 For example, in this code:
394 \snippet code/src_qtestlib_qtestcase.cpp 26
396 The testdata file will be resolved as the first existing file from:
399 \li \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
400 \li \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
401 \li \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
404 This allows the test to find its testdata regardless of whether the
405 test has been installed, and regardless of whether the test's build tree
406 is equal to the test's source tree.
408 \b {Note:} reliable detection of testdata from the source directory requires
409 either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
410 point to the working directory from which the compiler is invoked, or only
411 absolute paths to the source files are passed to the compiler. Otherwise, the
412 absolute path of the source directory cannot be determined.
414 \b {Note:} For tests that use the \l QTEST_APPLESS_MAIN() macro to generate a
415 \c{main()} function, \c{QFINDTESTDATA} will not attempt to find test data
416 relative to QCoreApplication::applicationDirPath(). In practice, this means that
417 tests using \c{QTEST_APPLESS_MAIN()} will fail to find their test data
418 if run from a shadow build tree.
421 /*! \macro QTEST_MAIN(TestClass)
425 Implements a main() function that instantiates an application object and
426 the \a TestClass, and executes all tests in the order they were defined.
427 Use this macro to build stand-alone executables.
429 If \c QT_WIDGETS_LIB is defined, the application object will be a QApplication,
430 if \c QT_GUI_LIB is defined, the application object will be a QGuiApplication,
431 otherwise it will be a QCoreApplication. If qmake is used and the configuration
432 includes \c{QT += widgets}, then \c QT_WIDGETS_LIB will be defined automatically.
433 Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
434 \c QT_GUI_LIB will be defined automatically.
436 \b {Note:} On platforms that have keypad navigation enabled by default,
437 this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
438 to simplify the usage of key events when writing autotests. If you wish to write a
439 test case that uses keypad navigation, you should enable it either in the
440 \c {initTestCase()} or \c {init()} functions of your test case by calling
441 \l {QApplication::setNavigationMode()}.
444 \snippet code/src_qtestlib_qtestcase.cpp 11
446 \sa QTEST_APPLESS_MAIN(), QTEST_GUILESS_MAIN(), QTest::qExec(),
447 QApplication::setNavigationMode()
450 /*! \macro QTEST_APPLESS_MAIN(TestClass)
454 Implements a main() function that executes all tests in \a TestClass.
456 Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
457 object. Use this macro for really simple stand-alone non-GUI tests.
462 /*! \macro QTEST_GUILESS_MAIN(TestClass)
467 Implements a main() function that instantiates a QCoreApplication object
468 and the \a TestClass, and executes all tests in the order they were
469 defined. Use this macro to build stand-alone executables.
471 Behaves like \l QTEST_MAIN(), but instantiates a QCoreApplication instead
472 of the QApplication object. Use this macro if your test case doesn't need
473 functionality offered by QApplication, but the event loop is still necessary.
483 This macro is used to measure the performance of code within a test.
484 The code to be benchmarked is contained within a code block following
489 \snippet qtestlib/tutorial5/benchmarking.cpp 0
491 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
492 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
496 \macro QBENCHMARK_ONCE
501 \brief The QBENCHMARK_ONCE macro is for measuring performance of a
502 code block by running it once.
504 This macro is used to measure the performance of code within a test.
505 The code to be benchmarked is contained within a code block following
508 Unlike QBENCHMARK, the contents of the contained code block is only run
509 once. The elapsed time will be reported as "0" if it's to short to
510 be measured by the selected backend. (Use)
512 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
513 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
516 /*! \enum QTest::TestFailMode
518 This enum describes the modes for handling an expected failure of the
519 \l QVERIFY() or \l QCOMPARE() macros.
521 \value Abort Aborts the execution of the test. Use this mode when it
522 doesn't make sense to execute the test any further after the
525 \value Continue Continues execution of the test after the expected failure.
530 /*! \enum QTest::KeyAction
532 This enum describes possible actions for key handling.
534 \value Press The key is pressed.
535 \value Release The key is released.
536 \value Click The key is clicked (pressed and released).
539 /*! \enum QTest::MouseAction
541 This enum describes possible actions for mouse handling.
543 \value MousePress A mouse button is pressed.
544 \value MouseRelease A mouse button is released.
545 \value MouseClick A mouse button is clicked (pressed and released).
546 \value MouseDClick A mouse button is double clicked (pressed and released twice).
547 \value MouseMove The mouse pointer has moved.
550 /*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
554 Simulates clicking of \a key with an optional \a modifier on a \a widget.
555 If \a delay is larger than 0, the test will wait for \a delay milliseconds
556 before clicking the key.
559 \snippet code/src_qtestlib_qtestcase.cpp 13
561 The example above simulates clicking \c a on \c myWidget without
562 any keyboard modifiers and without delay of the test.
564 \sa QTest::keyClicks()
567 /*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
569 Simulates clicking of \a key with an optional \a modifier on a \a widget.
570 If \a delay is larger than 0, the test will wait for \a delay milliseconds
571 before clicking the key.
574 \snippet code/src_qtestlib_qtestcase.cpp 14
576 The first example above simulates clicking the \c escape key on \c
577 myWidget without any keyboard modifiers and without delay. The
578 second example simulates clicking \c shift-escape on \c myWidget
579 following a 200 ms delay of the test.
581 \sa QTest::keyClicks()
584 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
586 Sends a Qt key event to \a widget with the given \a key and an associated \a action.
587 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
588 (in milliseconds) of the test before sending the event.
591 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
595 Sends a Qt key event to \a widget with the given key \a ascii and an associated \a action.
596 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
597 (in milliseconds) of the test before sending the event.
601 /*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
603 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
604 is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
606 \b {Note:} At some point you should release the key using \l keyRelease().
608 \sa QTest::keyRelease(), QTest::keyClick()
611 /*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
615 Simulates pressing a \a key with an optional \a modifier on a \a widget.
616 If \a delay is larger than 0, the test will wait for \a delay milliseconds
617 before pressing the key.
619 \b {Note:} At some point you should release the key using \l keyRelease().
621 \sa QTest::keyRelease(), QTest::keyClick()
624 /*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
626 Simulates releasing a \a key with an optional \a modifier on a \a widget.
627 If \a delay is larger than 0, the test will wait for \a delay milliseconds
628 before releasing the key.
630 \sa QTest::keyPress(), QTest::keyClick()
633 /*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
637 Simulates releasing a \a key with an optional \a modifier on a \a widget.
638 If \a delay is larger than 0, the test will wait for \a delay milliseconds
639 before releasing the key.
641 \sa QTest::keyClick()
645 /*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
647 Simulates clicking a \a sequence of keys on a \a
648 widget. Optionally, a keyboard \a modifier can be specified as
649 well as a \a delay (in milliseconds) of the test before each key
653 \snippet code/src_qtestlib_qtestcase.cpp 15
655 The example above simulates clicking the sequence of keys
656 representing "hello world" on \c myWidget without any keyboard
657 modifiers and without delay of the test.
659 \sa QTest::keyClick()
662 /*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
664 Simulates pressing a mouse \a button with an optional \a modifier
665 on a \a widget. The position is defined by \a pos; the default
666 position is the center of the widget. If \a delay is specified,
667 the test will wait for the specified amount of milliseconds before
670 \sa QTest::mouseRelease(), QTest::mouseClick()
673 /*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
675 Simulates releasing a mouse \a button with an optional \a modifier
676 on a \a widget. The position of the release is defined by \a pos;
677 the default position is the center of the widget. If \a delay is
678 specified, the test will wait for the specified amount of
679 milliseconds before releasing the button.
681 \sa QTest::mousePress(), QTest::mouseClick()
684 /*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
686 Simulates clicking a mouse \a button with an optional \a modifier
687 on a \a widget. The position of the click is defined by \a pos;
688 the default position is the center of the widget. If \a delay is
689 specified, the test will wait for the specified amount of
690 milliseconds before pressing and before releasing the button.
692 \sa QTest::mousePress(), QTest::mouseRelease()
695 /*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
697 Simulates double clicking a mouse \a button with an optional \a
698 modifier on a \a widget. The position of the click is defined by
699 \a pos; the default position is the center of the widget. If \a
700 delay is specified, the test will wait for the specified amount of
701 milliseconds before each press and release.
703 \sa QTest::mouseClick()
706 /*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
708 Moves the mouse pointer to a \a widget. If \a pos is not
709 specified, the mouse pointer moves to the center of the widget. If
710 a \a delay (in milliseconds) is given, the test will wait before
711 moving the mouse pointer.
715 \fn char *QTest::toString(const T &value)
717 Returns a textual representation of \a value. This function is used by
718 \l QCOMPARE() to output verbose information in case of a test failure.
720 You can add specializations of this function to your test to enable
723 \b {Note:} The caller of toString() must delete the returned data
724 using \c{delete[]}. Your implementation should return a string
725 created with \c{new[]} or qstrdup().
729 \snippet code/src_qtestlib_qtestcase.cpp 16
731 The example above defines a toString() specialization for a class
732 called \c MyPoint. Whenever a comparison of two instances of \c
733 MyPoint fails, \l QCOMPARE() will call this function to output the
734 contents of \c MyPoint to the test log.
740 \fn char *QTest::toString(const QLatin1String &string)
743 Returns a textual representation of the given \a string.
747 \fn char *QTest::toString(const QString &string)
750 Returns a textual representation of the given \a string.
754 \fn char *QTest::toString(const QByteArray &ba)
757 Returns a textual representation of the byte array \a ba.
759 \sa QTest::toHexRepresentation()
763 \fn char *QTest::toString(const QTime &time)
766 Returns a textual representation of the given \a time.
770 \fn char *QTest::toString(const QDate &date)
773 Returns a textual representation of the given \a date.
777 \fn char *QTest::toString(const QDateTime &dateTime)
780 Returns a textual representation of the date and time specified by
785 \fn char *QTest::toString(const QChar &character)
788 Returns a textual representation of the given \a character.
792 \fn char *QTest::toString(const QPoint &point)
795 Returns a textual representation of the given \a point.
799 \fn char *QTest::toString(const QSize &size)
802 Returns a textual representation of the given \a size.
806 \fn char *QTest::toString(const QRect &rectangle)
809 Returns a textual representation of the given \a rectangle.
813 \fn char *QTest::toString(const QUrl &url)
817 Returns a textual representation of the given \a url.
821 \fn char *QTest::toString(const QPointF &point)
824 Returns a textual representation of the given \a point.
828 \fn char *QTest::toString(const QSizeF &size)
831 Returns a textual representation of the given \a size.
835 \fn char *QTest::toString(const QRectF &rectangle)
838 Returns a textual representation of the given \a rectangle.
842 \fn char *QTest::toString(const QVariant &variant)
845 Returns a textual representation of the given \a variant.
848 /*! \fn void QTest::qWait(int ms)
850 Waits for \a ms milliseconds. While waiting, events will be processed and
851 your test will stay responsive to user interface events or network communication.
854 \snippet code/src_qtestlib_qtestcase.cpp 17
856 The code above will wait until the network server is responding for a
857 maximum of about 12.5 seconds.
859 \sa QTest::qSleep(), QSignalSpy::wait()
862 /*! \fn bool QTest::qWaitForWindowExposed(QWindow *window, int timeout)
865 Waits for \a timeout milliseconds or until the \a window is exposed.
866 Returns true if \c window is exposed within \a timeout milliseconds, otherwise returns false.
868 This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
869 time after being asked to show itself on the screen.
871 \sa QTest::qWaitForWindowActive(), QWindow::isExposed()
874 /*! \fn bool QTest::qWaitForWindowActive(QWindow *window, int timeout)
877 Waits for \a timeout milliseconds or until the \a window is active.
879 Returns true if \c window is active within \a timeout milliseconds, otherwise returns false.
881 \sa QTest::qWaitForWindowExposed(), QWindow::isActive()
884 /*! \fn bool QTest::qWaitForWindowExposed(QWidget *widget, int timeout)
887 Waits for \a timeout milliseconds or until the \a widget's window is exposed.
888 Returns true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns false.
890 This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some
891 time after being asked to show itself on the screen.
893 \sa QTest::qWaitForWindowActive()
896 /*! \fn bool QTest::qWaitForWindowActive(QWidget *widget, int timeout)
899 Waits for \a timeout milliseconds or until the \a widget's window is active.
901 Returns true if \c widget's window is active within \a timeout milliseconds, otherwise returns false.
903 \sa QTest::qWaitForWindowExposed(), QWidget::isActiveWindow()
906 /*! \fn bool QTest::qWaitForWindowShown(QWidget *widget, int timeout)
910 Waits for \a timeout milliseconds or until the \a widget's window is exposed.
911 Returns true if \c widget's window is exposed within \a timeout milliseconds, otherwise returns false.
913 This function does the same as qWaitForWindowExposed().
916 \snippet code/src_qtestlib_qtestcase.cpp 24
918 \sa QTest::qWaitForWindowActive(), QTest::qWaitForWindowExposed()
922 \class QTest::QTouchEventSequence
926 \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
928 To simulate a sequence of touch events on a specific device for a window or widget, call
929 QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
930 the sequence by calling press(), move(), release() and stationary(), and let the
931 instance run out of scope to commit the sequence to the event system.
934 \snippet code/src_qtestlib_qtestcase.cpp 25
938 \fn QTest::QTouchEventSequence::~QTouchEventSequence()
940 Commits this sequence of touch events, unless autoCommit was disabled, and frees allocated resources.
944 \fn void QTest::QTouchEventSequence::commit(bool processEvents)
946 Commits this sequence of touch events to the event system. Normally there is no need to call this
947 function because it is called from the destructor. However, if autoCommit is disabled, the events
948 only get committed upon explicitly calling this function.
950 In special cases tests may want to disable the processing of the events. This can be achieved by
951 setting \a processEvents to false. This results in merely queuing the events, the event loop will
952 not be forced to process them.
956 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWindow *window)
959 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
960 a reference to this QTouchEventSequence.
962 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
963 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
965 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
969 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
971 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
972 a reference to this QTouchEventSequence.
974 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
975 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
977 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
981 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWindow *window)
984 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
985 a reference to this QTouchEventSequence.
987 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
988 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
990 Simulates that the user moved the finger identified by \a touchId.
994 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
996 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
997 a reference to this QTouchEventSequence.
999 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
1000 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
1002 Simulates that the user moved the finger identified by \a touchId.
1006 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWindow *window)
1009 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
1010 a reference to this QTouchEventSequence.
1012 The position \a pt is interpreted as relative to \a window. If \a window is the null pointer, then
1013 \a pt is interpreted as relative to the window provided when instantiating this QTouchEventSequence.
1015 Simulates that the user lifted the finger identified by \a touchId.
1019 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
1021 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
1022 a reference to this QTouchEventSequence.
1024 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
1025 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
1027 Simulates that the user lifted the finger identified by \a touchId.
1031 \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
1033 Adds a stationary event for touchpoint \a touchId to this sequence and returns
1034 a reference to this QTouchEventSequence.
1036 Simulates that the user did not move the finger identified by \a touchId.
1040 \fn QTouchEventSequence QTest::touchEvent(QWindow *window, QTouchDevice *device, bool autoCommit = true)
1043 Creates and returns a QTouchEventSequence for the \a device to
1044 simulate events for \a window.
1046 When adding touch events to the sequence, \a window will also be used to translate
1047 the position provided to screen coordinates, unless another window is provided in the
1048 respective calls to press(), move() etc.
1050 The touch events are committed to the event system when the destructor of the
1051 QTouchEventSequence is called (ie when the object returned runs out of scope), unless
1052 \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
1057 \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchDevice *device, bool autoCommit = true)
1059 Creates and returns a QTouchEventSequence for the \a device to
1060 simulate events for \a widget.
1062 When adding touch events to the sequence, \a widget will also be used to translate
1063 the position provided to screen coordinates, unless another widget is provided in the
1064 respective calls to press(), move() etc.
1066 The touch events are committed to the event system when the destructor of the
1067 QTouchEventSequence is called (ie when the object returned runs out of scope), unless
1068 \a autoCommit is set to false. When \a autoCommit is false, commit() has to be called
1072 static bool installCoverageTool(const char * appname, const char * testname)
1074 #ifdef __COVERAGESCANNER__
1075 if (!qEnvironmentVariableIsEmpty("QT_TESTCOCOON_ACTIVE"))
1077 // Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from
1078 // being considered as a stand-alone test regarding the coverage analysis.
1079 qputenv("QT_TESTCOCOON_ACTIVE", "1");
1081 // Install Coverage Tool
1082 __coveragescanner_install(appname);
1083 __coveragescanner_testname(testname);
1084 __coveragescanner_clear();
1095 static QObject *currentTestObject = 0;
1097 class TestFunction {
1099 TestFunction() : function_(-1), data_(0) {}
1100 void set(int function, char *data) { function_ = function; data_ = data; }
1101 char *data() const { return data_; }
1102 int function() const { return function_; }
1103 ~TestFunction() { delete[] data_; }
1109 * Contains the list of test functions that was supplied
1110 * on the command line, if any. Hence, if not empty,
1111 * those functions should be run instead of
1112 * all appearing in the test case.
1114 static TestFunction * testFuncs = 0;
1115 static int testFuncCount = 0;
1117 /** Don't leak testFuncs on exit even on error */
1118 static struct TestFuncCleanup
1127 ~TestFuncCleanup() { cleanup(); }
1130 static int keyDelay = -1;
1131 static int mouseDelay = -1;
1132 static int eventDelay = -1;
1133 #if defined(Q_OS_UNIX)
1134 static bool noCrashHandler = false;
1138 Invoke a method of the object without generating warning if the method does not exist
1140 static void invokeMethod(QObject *obj, const char *methodName)
1142 const QMetaObject *metaObject = obj->metaObject();
1143 int funcIndex = metaObject->indexOfMethod(methodName);
1144 if (funcIndex >= 0) {
1145 QMetaMethod method = metaObject->method(funcIndex);
1146 method.invoke(obj, Qt::DirectConnection);
1150 int defaultEventDelay()
1152 if (eventDelay == -1) {
1153 const QByteArray env = qgetenv("QTEST_EVENT_DELAY");
1155 eventDelay = atoi(env.constData());
1162 int Q_TESTLIB_EXPORT defaultMouseDelay()
1164 if (mouseDelay == -1) {
1165 const QByteArray env = qgetenv("QTEST_MOUSEEVENT_DELAY");
1167 mouseDelay = atoi(env.constData());
1169 mouseDelay = defaultEventDelay();
1174 int Q_TESTLIB_EXPORT defaultKeyDelay()
1176 if (keyDelay == -1) {
1177 const QByteArray env = qgetenv("QTEST_KEYEVENT_DELAY");
1179 keyDelay = atoi(env.constData());
1181 keyDelay = defaultEventDelay();
1186 static bool isValidSlot(const QMetaMethod &sl)
1188 if (sl.access() != QMetaMethod::Private || sl.parameterCount() != 0
1189 || sl.returnType() != QMetaType::Void || sl.methodType() != QMetaMethod::Slot)
1191 QByteArray name = sl.name();
1194 if (name.endsWith("_data"))
1196 if (name == "initTestCase" || name == "cleanupTestCase"
1197 || name == "cleanup" || name == "init")
1202 Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
1203 Q_TESTLIB_EXPORT QStringList testFunctions;
1204 Q_TESTLIB_EXPORT QStringList testTags;
1206 static void qPrintTestSlots(FILE *stream, const char *filter = 0)
1208 for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
1209 QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
1210 if (isValidSlot(sl)) {
1211 const QByteArray signature = sl.methodSignature();
1212 if (!filter || QString::fromLatin1(signature).contains(QLatin1String(filter), Qt::CaseInsensitive))
1213 fprintf(stream, "%s\n", signature.constData());
1218 static void qPrintDataTags(FILE *stream)
1220 // Avoid invoking the actual test functions, and also avoid printing irrelevant output:
1221 QTestLog::setPrintAvailableTagsMode();
1223 // Get global data tags:
1224 QTestTable::globalTestTable();
1225 invokeMethod(QTest::currentTestObject, "initTestCase_data()");
1226 const QTestTable *gTable = QTestTable::globalTestTable();
1228 const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject();
1230 // Process test functions:
1231 for (int i = 0; i < currTestMetaObj->methodCount(); ++i) {
1232 QMetaMethod tf = currTestMetaObj->method(i);
1234 if (isValidSlot(tf)) {
1236 // Retrieve local tags:
1237 QStringList localTags;
1239 char *slot = qstrdup(tf.methodSignature().constData());
1240 slot[strlen(slot) - 2] = '\0';
1242 member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
1243 qsnprintf(member.data(), member.size(), "%s_data()", slot);
1244 invokeMethod(QTest::currentTestObject, member.constData());
1245 for (int j = 0; j < table.dataCount(); ++j)
1246 localTags << QLatin1String(table.testData(j)->dataTag());
1248 // Print all tag combinations:
1249 if (gTable->dataCount() == 0) {
1250 if (localTags.count() == 0) {
1251 // No tags at all, so just print the test function:
1252 fprintf(stream, "%s %s\n", currTestMetaObj->className(), slot);
1254 // Only local tags, so print each of them:
1255 for (int k = 0; k < localTags.size(); ++k)
1257 stream, "%s %s %s\n",
1258 currTestMetaObj->className(), slot, localTags.at(k).toLatin1().data());
1261 for (int j = 0; j < gTable->dataCount(); ++j) {
1262 if (localTags.count() == 0) {
1263 // Only global tags, so print the current one:
1265 stream, "%s %s __global__ %s\n",
1266 currTestMetaObj->className(), slot, gTable->testData(j)->dataTag());
1268 // Local and global tags, so print each of the local ones and
1269 // the current global one:
1270 for (int k = 0; k < localTags.size(); ++k)
1272 stream, "%s %s %s __global__ %s\n", currTestMetaObj->className(), slot,
1273 localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag());
1283 static int qToInt(char *str)
1286 int l = (int)strtol(str, &pEnd, 10);
1288 fprintf(stderr, "Invalid numeric parameter: '%s'\n", str);
1294 Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
1296 QTestLog::LogMode logFormat = QTestLog::Plain;
1297 const char *logFilename = 0;
1299 const char *testOptions =
1300 " New-style logging options:\n"
1301 " -o filename,format : Output results to file in the specified format\n"
1302 " Use - to output to stdout\n"
1303 " Valid formats are:\n"
1304 " txt : Plain text\n"
1305 " xunitxml : XML XUnit document\n"
1306 " xml : XML document\n"
1307 " lightxml : A stream of XML tags\n"
1309 " *** Multiple loggers can be specified, but at most one can log to stdout.\n"
1311 " Old-style logging options:\n"
1312 " -o filename : Write the output into file\n"
1313 " -txt : Output results in Plain Text\n"
1314 " -xunitxml : Output results as XML XUnit document\n"
1315 " -xml : Output results as XML document\n"
1316 " -lightxml : Output results as stream of XML tags\n"
1318 " *** If no output file is specified, stdout is assumed.\n"
1319 " *** If no output format is specified, -txt is assumed.\n"
1321 " Test log detail options:\n"
1322 " -silent : Log failures and fatal errors only\n"
1323 " -v1 : Log the start of each testfunction\n"
1324 " -v2 : Log each QVERIFY/QCOMPARE/QTEST (implies -v1)\n"
1325 " -vs : Log every signal emission and resulting slot invocations\n"
1327 " *** The -silent and -v1 options only affect plain text output.\n"
1329 " Testing options:\n"
1330 " -functions : Returns a list of current testfunctions\n"
1331 " -datatags : Returns a list of current data tags.\n"
1332 " A global data tag is preceded by ' __global__ '.\n"
1333 " -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
1334 " -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
1335 " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
1336 " -maxwarnings n : Sets the maximum amount of messages to output.\n"
1337 " 0 means unlimited, default: 2000\n"
1338 #if defined(Q_OS_UNIX)
1339 " -nocrashhandler : Disables the crash handler\n"
1342 " Benchmarking options:\n"
1343 #ifdef QTESTLIB_USE_VALGRIND
1344 " -callgrind : Use callgrind to time benchmarks\n"
1346 #ifdef HAVE_TICK_COUNTER
1347 " -tickcounter : Use CPU tick counters to time benchmarks\n"
1349 " -eventcounter : Counts events received during benchmarks\n"
1350 " -minimumvalue n : Sets the minimum acceptable measurement value\n"
1351 " -iterations n : Sets the number of accumulation iterations.\n"
1352 " -median n : Sets the number of median iterations.\n"
1353 " -vb : Print out verbose benchmarking information.\n";
1355 for (int i = 1; i < argc; ++i) {
1356 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0
1357 || strcmp(argv[i], "/?") == 0) {
1358 printf(" Usage: %s [options] [testfunction[:testdata]]...\n"
1359 " By default, all testfunctions will be run.\n\n"
1360 "%s", argv[0], testOptions);
1364 " QmlTest options:\n"
1365 " -import dir : Specify an import directory.\n"
1366 " -input dir/file : Specify the root directory for test cases or a single test case file.\n"
1367 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1368 " -translation file : Specify the translation file.\n"
1373 " -help : This help\n");
1375 } else if (strcmp(argv[i], "-functions") == 0) {
1377 QTest::printAvailableFunctions = true;
1379 qPrintTestSlots(stdout);
1382 } else if (strcmp(argv[i], "-datatags") == 0) {
1384 qPrintDataTags(stdout);
1387 } else if (strcmp(argv[i], "-txt") == 0) {
1388 logFormat = QTestLog::Plain;
1389 } else if (strcmp(argv[i], "-xunitxml") == 0) {
1390 logFormat = QTestLog::XunitXML;
1391 } else if (strcmp(argv[i], "-xml") == 0) {
1392 logFormat = QTestLog::XML;
1393 } else if (strcmp(argv[i], "-lightxml") == 0) {
1394 logFormat = QTestLog::LightXML;
1395 } else if (strcmp(argv[i], "-silent") == 0) {
1396 QTestLog::setVerboseLevel(-1);
1397 } else if (strcmp(argv[i], "-v1") == 0) {
1398 QTestLog::setVerboseLevel(1);
1399 } else if (strcmp(argv[i], "-v2") == 0) {
1400 QTestLog::setVerboseLevel(2);
1401 } else if (strcmp(argv[i], "-vs") == 0) {
1402 QSignalDumper::startDump();
1403 } else if (strcmp(argv[i], "-o") == 0) {
1404 if (i + 1 >= argc) {
1405 fprintf(stderr, "-o needs an extra parameter specifying the filename and optional format\n");
1409 // Do we have the old or new style -o option?
1410 char *filename = new char[strlen(argv[i])+1];
1411 char *format = new char[strlen(argv[i])+1];
1412 if (sscanf(argv[i], "%[^,],%s", filename, format) == 1) {
1414 logFilename = argv[i];
1417 if (strcmp(format, "txt") == 0)
1418 logFormat = QTestLog::Plain;
1419 else if (strcmp(format, "lightxml") == 0)
1420 logFormat = QTestLog::LightXML;
1421 else if (strcmp(format, "xml") == 0)
1422 logFormat = QTestLog::XML;
1423 else if (strcmp(format, "xunitxml") == 0)
1424 logFormat = QTestLog::XunitXML;
1426 fprintf(stderr, "output format must be one of txt, lightxml, xml or xunitxml\n");
1429 if (strcmp(filename, "-") == 0 && QTestLog::loggerUsingStdout()) {
1430 fprintf(stderr, "only one logger can log to stdout\n");
1433 QTestLog::addLogger(logFormat, filename);
1437 } else if (strcmp(argv[i], "-eventdelay") == 0) {
1438 if (i + 1 >= argc) {
1439 fprintf(stderr, "-eventdelay needs an extra parameter to indicate the delay(ms)\n");
1442 QTest::eventDelay = qToInt(argv[++i]);
1444 } else if (strcmp(argv[i], "-keydelay") == 0) {
1445 if (i + 1 >= argc) {
1446 fprintf(stderr, "-keydelay needs an extra parameter to indicate the delay(ms)\n");
1449 QTest::keyDelay = qToInt(argv[++i]);
1451 } else if (strcmp(argv[i], "-mousedelay") == 0) {
1452 if (i + 1 >= argc) {
1453 fprintf(stderr, "-mousedelay needs an extra parameter to indicate the delay(ms)\n");
1456 QTest::mouseDelay = qToInt(argv[++i]);
1458 } else if (strcmp(argv[i], "-maxwarnings") == 0) {
1459 if (i + 1 >= argc) {
1460 fprintf(stderr, "-maxwarnings needs an extra parameter with the amount of warnings\n");
1463 QTestLog::setMaxWarnings(qToInt(argv[++i]));
1465 #if defined(Q_OS_UNIX)
1466 } else if (strcmp(argv[i], "-nocrashhandler") == 0) {
1467 QTest::noCrashHandler = true;
1469 #ifdef QTESTLIB_USE_VALGRIND
1470 } else if (strcmp(argv[i], "-callgrind") == 0) {
1471 if (QBenchmarkValgrindUtils::haveValgrind())
1472 if (QFileInfo(QDir::currentPath()).isWritable()) {
1473 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindParentProcess);
1475 fprintf(stderr, "WARNING: Current directory not writable. Using the walltime measurer.\n");
1478 fprintf(stderr, "WARNING: Valgrind not found or too old. Make sure it is installed and in your path. "
1479 "Using the walltime measurer.\n");
1481 } else if (strcmp(argv[i], "-callgrindchild") == 0) { // "private" option
1482 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindChildProcess);
1483 QBenchmarkGlobalData::current->callgrindOutFileBase =
1484 QBenchmarkValgrindUtils::outFileBase();
1486 #ifdef HAVE_TICK_COUNTER
1487 } else if (strcmp(argv[i], "-tickcounter") == 0) {
1488 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::TickCounter);
1490 } else if (strcmp(argv[i], "-eventcounter") == 0) {
1491 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::EventCounter);
1492 } else if (strcmp(argv[i], "-minimumvalue") == 0) {
1493 if (i + 1 >= argc) {
1494 fprintf(stderr, "-minimumvalue needs an extra parameter to indicate the minimum time(ms)\n");
1497 QBenchmarkGlobalData::current->walltimeMinimum = qToInt(argv[++i]);
1499 } else if (strcmp(argv[i], "-iterations") == 0) {
1500 if (i + 1 >= argc) {
1501 fprintf(stderr, "-iterations needs an extra parameter to indicate the number of iterations\n");
1504 QBenchmarkGlobalData::current->iterationCount = qToInt(argv[++i]);
1506 } else if (strcmp(argv[i], "-median") == 0) {
1507 if (i + 1 >= argc) {
1508 fprintf(stderr, "-median needs an extra parameter to indicate the number of median iterations\n");
1511 QBenchmarkGlobalData::current->medianIterationCount = qToInt(argv[++i]);
1514 } else if (strcmp(argv[i], "-vb") == 0) {
1515 QBenchmarkGlobalData::current->verboseOutput = true;
1516 } else if (argv[i][0] == '-') {
1517 fprintf(stderr, "Unknown option: '%s'\n\n%s", argv[i], testOptions);
1519 fprintf(stderr, "\nqmltest related options:\n"
1520 " -import : Specify an import directory.\n"
1521 " -input : Specify the root directory for test cases.\n"
1522 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1526 fprintf(stderr, "\n"
1527 " -help : This help\n");
1530 // We can't check the availability of test functions until
1531 // we load the QML files. So just store the data for now.
1534 for (offset = 0; *(argv[i]+offset); ++offset) {
1535 if (*(argv[i]+offset) == ':') {
1536 if (*(argv[i]+offset+1) == ':') {
1537 // "::" is used as a test name separator.
1538 // e.g. "ClickTests::test_click:row1".
1547 QTest::testFunctions += QString::fromLatin1(argv[i]);
1548 QTest::testTags += QString();
1550 QTest::testFunctions +=
1551 QString::fromLatin1(argv[i], colon);
1553 QString::fromLatin1(argv[i] + colon + 1);
1556 if (!QTest::testFuncs) {
1557 QTest::testFuncs = new QTest::TestFunction[512];
1561 char buf[512], *data=0;
1563 for (off = 0; *(argv[i]+off); ++off) {
1564 if (*(argv[i]+off) == ':') {
1570 data = qstrdup(argv[i]+colon+1);
1572 qsnprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
1573 qsnprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
1574 int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
1575 if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
1576 fprintf(stderr, "Unknown test function: '%s'. Possible matches:\n", buf);
1578 qPrintTestSlots(stderr, buf);
1579 fprintf(stderr, "\n%s -functions\nlists all available test functions.\n", argv[0]);
1582 testFuncs[testFuncCount].set(idx, data);
1584 QTEST_ASSERT(QTest::testFuncCount < 512);
1588 bool installedTestCoverage = installCoverageTool(QTestResult::currentAppname(), QTestResult::currentTestObjectName());
1589 QTestLog::setInstalledTestCoverage(installedTestCoverage);
1591 // If no loggers were created by the long version of the -o command-line
1592 // option, create a logger using whatever filename and format were
1593 // set using the old-style command-line options.
1594 if (QTestLog::loggerCount() == 0)
1595 QTestLog::addLogger(logFormat, logFilename);
1598 QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
1600 const int count = container.count();
1602 return QBenchmarkResult();
1605 return container.at(0);
1607 QList<QBenchmarkResult> containerCopy = container;
1608 qSort(containerCopy);
1610 const int middle = count / 2;
1612 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
1613 return containerCopy.at(middle);
1616 struct QTestDataSetter
1618 QTestDataSetter(QTestData *data)
1620 QTestResult::setCurrentTestData(data);
1624 QTestResult::setCurrentTestData(0);
1628 static void qInvokeTestMethodDataEntry(char *slot)
1630 /* Benchmarking: for each median iteration*/
1632 bool isBenchmark = false;
1633 int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
1635 QList<QBenchmarkResult> results;
1637 QBenchmarkTestMethodData::current->beginDataRun();
1639 /* Benchmarking: for each accumulation iteration*/
1642 invokeMethod(QTest::currentTestObject, "init()");
1643 if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed())
1646 QBenchmarkTestMethodData::current->result = QBenchmarkResult();
1647 QBenchmarkTestMethodData::current->resultAccepted = false;
1649 QBenchmarkGlobalData::current->context.tag =
1651 QTestResult::currentDataTag()
1652 ? QTestResult::currentDataTag() : "");
1654 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
1655 Qt::DirectConnection);
1657 QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
1659 isBenchmark = QBenchmarkTestMethodData::current->isBenchmark();
1661 QTestResult::finishedCurrentTestData();
1663 invokeMethod(QTest::currentTestObject, "cleanup()");
1665 // If the test isn't a benchmark, finalize the result after cleanup() has finished.
1667 QTestResult::finishedCurrentTestDataCleanup();
1669 // If this test method has a benchmark, repeat until all measurements are
1671 // The QBENCHMARK macro increases the number of iterations for each run until
1673 } while (invokeOk && isBenchmark
1674 && QBenchmarkTestMethodData::current->resultsAccepted() == false
1675 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1677 QBenchmarkTestMethodData::current->endDataRun();
1678 if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) {
1679 if (i > -1) // iteration -1 is the warmup iteration.
1680 results.append(QBenchmarkTestMethodData::current->result);
1682 if (isBenchmark && QBenchmarkGlobalData::current->verboseOutput) {
1684 QTestLog::info(qPrintable(
1685 QString::fromLatin1("warmup stage result : %1")
1686 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1688 QTestLog::info(qPrintable(
1689 QString::fromLatin1("accumulation stage result: %1")
1690 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1694 } while (isBenchmark
1695 && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount())
1696 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1698 // If the test is a benchmark, finalize the result after all iterations have finished.
1700 bool testPassed = !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed();
1701 QTestResult::finishedCurrentTestDataCleanup();
1702 // Only report benchmark figures if the test passed
1703 if (testPassed && QBenchmarkTestMethodData::current->resultsAccepted())
1704 QTestLog::addBenchmarkResult(qMedian(results));
1711 Call slot_data(), init(), slot(), cleanup(), init(), slot(), cleanup(), ...
1712 If data is set then it is the only test that is performed
1714 If the function was successfully called, true is returned, otherwise
1717 static bool qInvokeTestMethod(const char *slotName, const char *data=0)
1719 QTEST_ASSERT(slotName);
1721 QBenchmarkTestMethodData benchmarkData;
1722 QBenchmarkTestMethodData::current = &benchmarkData;
1724 QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
1729 char *slot = qstrdup(slotName);
1730 slot[strlen(slot) - 2] = '\0';
1731 QTestResult::setCurrentTestFunction(slot);
1733 const QTestTable *gTable = QTestTable::globalTestTable();
1734 const int globalDataCount = gTable->dataCount();
1735 int curGlobalDataIndex = 0;
1737 /* For each test function that has a *_data() table/function, do: */
1739 if (!gTable->isEmpty())
1740 QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
1742 if (curGlobalDataIndex == 0) {
1743 qsnprintf(member, 512, "%s_data()", slot);
1744 invokeMethod(QTest::currentTestObject, member);
1747 bool foundFunction = false;
1748 if (!QTestResult::skipCurrentTest()) {
1749 int curDataIndex = 0;
1750 const int dataCount = table.dataCount();
1752 // Data tag requested but none available?
1753 if (data && !dataCount) {
1754 // Let empty data tag through.
1758 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1759 fprintf(stderr, "Function has no testdata.\n");
1764 /* For each entry in the data table, do: */
1766 QTestResult::setSkipCurrentTest(false);
1767 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
1768 foundFunction = true;
1769 QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
1770 : table.testData(curDataIndex));
1772 qInvokeTestMethodDataEntry(slot);
1778 } while (curDataIndex < dataCount);
1781 if (data && !foundFunction) {
1782 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1783 fprintf(stderr, "Available testdata:\n");
1784 for (int i = 0; i < table.dataCount(); ++i)
1785 fprintf(stderr, "%s\n", table.testData(i)->dataTag());
1789 QTestResult::setCurrentGlobalTestData(0);
1790 ++curGlobalDataIndex;
1791 } while (curGlobalDataIndex < globalDataCount);
1793 QTestResult::finishedCurrentTestFunction();
1794 QTestResult::setSkipCurrentTest(false);
1795 QTestResult::setCurrentTestData(0);
1801 void *fetchData(QTestData *data, const char *tagName, int typeId)
1803 QTEST_ASSERT(typeId);
1804 QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");
1805 QTEST_ASSERT(data->parent());
1807 int idx = data->parent()->indexOf(tagName);
1809 if (idx == -1 || idx >= data->dataCount()) {
1810 qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
1814 if (typeId != data->parent()->elementTypeId(idx)) {
1815 qFatal("Requested type '%s' does not match available type '%s'.",
1816 QMetaType::typeName(typeId),
1817 QMetaType::typeName(data->parent()->elementTypeId(idx)));
1820 return data->data(idx);
1824 \fn char* QTest::toHexRepresentation(const char *ba, int length)
1826 Returns a pointer to a string that is the string \a ba represented
1827 as a space-separated sequence of hex characters. If the input is
1828 considered too long, it is truncated. A trucation is indicated in
1829 the returned string as an ellipsis at the end.
1831 \a length is the length of the string \a ba.
1833 char *toHexRepresentation(const char *ba, int length)
1838 /* We output at maximum about maxLen characters in order to avoid
1839 * running out of memory and flooding things when the byte array
1842 * maxLen can't be for example 200 because QTestLib is sprinkled with fixed
1845 const int maxLen = 50;
1846 const int len = qMin(maxLen, length);
1849 if (length > maxLen) {
1850 const int size = len * 3 + 4;
1851 result = new char[size];
1853 char *const forElipsis = result + size - 5;
1854 forElipsis[0] = ' ';
1855 forElipsis[1] = '.';
1856 forElipsis[2] = '.';
1857 forElipsis[3] = '.';
1858 result[size - 1] = '\0';
1861 const int size = len * 3;
1862 result = new char[size];
1863 result[size - 1] = '\0';
1866 const char toHex[] = "0123456789ABCDEF";
1871 const char at = ba[i];
1873 result[o] = toHex[(at >> 4) & 0x0F];
1875 result[o] = toHex[at & 0x0F];
1890 static void qInvokeTestMethods(QObject *testObject)
1892 const QMetaObject *metaObject = testObject->metaObject();
1893 QTEST_ASSERT(metaObject);
1894 QTestLog::startLogging();
1895 QTestResult::setCurrentTestFunction("initTestCase");
1896 QTestTable::globalTestTable();
1897 invokeMethod(testObject, "initTestCase_data()");
1899 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
1900 invokeMethod(testObject, "initTestCase()");
1902 // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy.
1903 const bool previousFailed = QTestResult::currentTestFailed();
1904 QTestResult::finishedCurrentTestData();
1905 QTestResult::finishedCurrentTestDataCleanup();
1906 QTestResult::finishedCurrentTestFunction();
1908 if (!QTestResult::skipCurrentTest() && !previousFailed) {
1910 if (QTest::testFuncs) {
1911 for (int i = 0; i != QTest::testFuncCount; i++) {
1912 if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).methodSignature().constData(),
1913 QTest::testFuncs[i].data())) {
1917 testFuncCleaner.cleanup();
1919 int methodCount = metaObject->methodCount();
1920 QMetaMethod *testMethods = new QMetaMethod[methodCount];
1921 for (int i = 0; i != methodCount; i++)
1922 testMethods[i] = metaObject->method(i);
1923 for (int i = 0; i != methodCount; i++) {
1924 if (!isValidSlot(testMethods[i]))
1926 if (!qInvokeTestMethod(testMethods[i].methodSignature().constData()))
1929 delete[] testMethods;
1934 QTestResult::setSkipCurrentTest(false);
1935 QTestResult::setCurrentTestFunction("cleanupTestCase");
1936 invokeMethod(testObject, "cleanupTestCase()");
1937 QTestResult::finishedCurrentTestData();
1938 QTestResult::finishedCurrentTestDataCleanup();
1940 QTestResult::finishedCurrentTestFunction();
1941 QTestResult::setCurrentTestFunction(0);
1942 QTestTable::clearGlobalTestTable();
1944 QTestLog::stopLogging();
1947 #if defined(Q_OS_UNIX)
1948 class FatalSignalHandler
1951 FatalSignalHandler();
1952 ~FatalSignalHandler();
1955 static void signal(int);
1956 sigset_t handledSignals;
1959 void FatalSignalHandler::signal(int signum)
1961 qFatal("Received signal %d", signum);
1962 #if defined(Q_OS_INTEGRITY)
1964 struct sigaction act;
1965 memset(&act, 0, sizeof(struct sigaction));
1966 act.sa_handler = SIG_DFL;
1967 sigaction(signum, &act, NULL);
1972 FatalSignalHandler::FatalSignalHandler()
1974 sigemptyset(&handledSignals);
1976 const int fatalSignals[] = {
1977 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 };
1979 struct sigaction act;
1980 memset(&act, 0, sizeof(act));
1981 act.sa_handler = FatalSignalHandler::signal;
1983 // Remove the handler after it is invoked.
1984 #if !defined(Q_OS_INTEGRITY)
1985 act.sa_flags = SA_RESETHAND;
1987 // Block all fatal signals in our signal handler so we don't try to close
1988 // the testlog twice.
1989 sigemptyset(&act.sa_mask);
1990 for (int i = 0; fatalSignals[i]; ++i)
1991 sigaddset(&act.sa_mask, fatalSignals[i]);
1993 struct sigaction oldact;
1995 for (int i = 0; fatalSignals[i]; ++i) {
1996 sigaction(fatalSignals[i], &act, &oldact);
1999 oldact.sa_flags & SA_SIGINFO ||
2001 oldact.sa_handler != SIG_DFL) {
2002 sigaction(fatalSignals[i], &oldact, 0);
2005 sigaddset(&handledSignals, fatalSignals[i]);
2011 FatalSignalHandler::~FatalSignalHandler()
2013 // Unregister any of our remaining signal handlers
2014 struct sigaction act;
2015 memset(&act, 0, sizeof(act));
2016 act.sa_handler = SIG_DFL;
2018 struct sigaction oldact;
2020 for (int i = 1; i < 32; ++i) {
2021 if (!sigismember(&handledSignals, i))
2023 sigaction(i, &act, &oldact);
2025 // If someone overwrote it in the mean time, put it back
2026 if (oldact.sa_handler != FatalSignalHandler::signal)
2027 sigaction(i, &oldact, 0);
2037 Executes tests declared in \a testObject. In addition, the private slots
2038 \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
2039 are executed if they exist. See \l{Creating a Test} for more details.
2041 Optionally, the command line arguments \a argc and \a argv can be provided.
2042 For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.
2044 The following example will run all tests in \c MyTestObject:
2046 \snippet code/src_qtestlib_qtestcase.cpp 18
2048 This function returns 0 if no tests failed, or a value other than 0 if one
2049 or more tests failed or in case of unhandled exceptions. (Skipped tests do
2050 not influence the return value.)
2052 For stand-alone test applications, the convenience macro \l QTEST_MAIN() can
2053 be used to declare a main() function that parses the command line arguments
2054 and executes the tests, avoiding the need to call this function explicitly.
2056 The return value from this function is also the exit code of the test
2057 application when the \l QTEST_MAIN() macro is used.
2059 For stand-alone test applications, this function should not be called more
2060 than once, as command-line options for logging test output to files and
2061 executing individual test functions will not behave correctly.
2063 Note: This function is not reentrant, only one test can run at a time. A
2064 test that was executed with qExec() can't run another test via qExec() and
2065 threads are not allowed to call qExec() simultaneously.
2067 If you have programatically created the arguments, as opposed to getting them
2068 from the arguments in \c main(), it is likely of interest to use
2069 QTest::qExec(QObject *, const QStringList &) since it is Unicode safe.
2074 int QTest::qExec(QObject *testObject, int argc, char **argv)
2076 QBenchmarkGlobalData benchmarkData;
2077 QBenchmarkGlobalData::current = &benchmarkData;
2079 #ifdef QTESTLIB_USE_VALGRIND
2080 int callgrindChildExitCode = 0;
2084 bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
2085 IOPMAssertionID powerID;
2087 #ifndef QT_NO_EXCEPTIONS
2091 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
2092 # if !defined(Q_CC_MINGW)
2093 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
2095 SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
2099 // Starting with Qt 4.4, applications launched from the command line
2100 // no longer get focus automatically. Since some tests might depend
2101 // on this, call SetFrontProcess here to get the pre 4.4 behavior.
2102 if (macNeedsActivate) {
2103 ProcessSerialNumber psn = { 0, kCurrentProcess };
2104 SetFrontProcess(&psn);
2105 IOReturn ok = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &powerID);
2106 if (ok != kIOReturnSuccess)
2107 macNeedsActivate = false; // no need to release the assertion on exit.
2111 QTestResult::reset();
2113 QTEST_ASSERT(testObject);
2114 QTEST_ASSERT(!currentTestObject);
2115 currentTestObject = testObject;
2117 const QMetaObject *metaObject = testObject->metaObject();
2118 QTEST_ASSERT(metaObject);
2120 QTestResult::setCurrentTestObject(metaObject->className());
2122 QTestResult::setCurrentAppname(argv[0]);
2124 qtest_qParseArgs(argc, argv, false);
2126 #ifdef QTESTLIB_USE_VALGRIND
2127 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
2128 const QStringList origAppArgs(QCoreApplication::arguments());
2129 if (!QBenchmarkValgrindUtils::rerunThroughCallgrind(origAppArgs, callgrindChildExitCode))
2132 QBenchmarkValgrindUtils::cleanup();
2137 #if defined(Q_OS_UNIX)
2138 QScopedPointer<FatalSignalHandler> handler;
2139 if (!noCrashHandler)
2140 handler.reset(new FatalSignalHandler);
2142 qInvokeTestMethods(testObject);
2145 #ifndef QT_NO_EXCEPTIONS
2147 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
2148 if (QTestResult::currentTestFunction()) {
2149 QTestResult::finishedCurrentTestFunction();
2150 QTestResult::setCurrentTestFunction(0);
2153 QTestLog::stopLogging();
2155 if (macNeedsActivate) {
2156 IOPMAssertionRelease(powerID);
2159 currentTestObject = 0;
2161 // Rethrow exception to make debugging easier.
2167 currentTestObject = 0;
2169 QSignalDumper::endDump();
2172 if (macNeedsActivate) {
2173 IOPMAssertionRelease(powerID);
2177 #ifdef QTESTLIB_USE_VALGRIND
2178 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
2179 return callgrindChildExitCode;
2181 // make sure our exit code is never going above 127
2182 // since that could wrap and indicate 0 test fails
2183 return qMin(QTestLog::failCount(), 127);
2190 Behaves identically to qExec(QObject *, int, char**) but takes a
2191 QStringList of \a arguments instead of a \c char** list.
2193 int QTest::qExec(QObject *testObject, const QStringList &arguments)
2195 const int argc = arguments.count();
2196 QVarLengthArray<char *> argv(argc);
2198 QVector<QByteArray> args;
2201 for (int i = 0; i < argc; ++i)
2203 args.append(arguments.at(i).toLocal8Bit().constData());
2204 argv[i] = args.last().data();
2207 return qExec(testObject, argc, argv.data());
2212 void QTest::qFail(const char *statementStr, const char *file, int line)
2214 QTestResult::addFailure(statementStr, file, line);
2219 bool QTest::qVerify(bool statement, const char *statementStr, const char *description,
2220 const char *file, int line)
2222 return QTestResult::verify(statement, statementStr, description, file, line);
2225 /*! \fn void QTest::qSkip(const char *message, const char *file, int line)
2228 void QTest::qSkip(const char *message, const char *file, int line)
2230 QTestResult::addSkip(message, file, line);
2231 QTestResult::setSkipCurrentTest(true);
2234 /*! \fn bool QTest::qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line)
2237 bool QTest::qExpectFail(const char *dataIndex, const char *comment,
2238 QTest::TestFailMode mode, const char *file, int line)
2240 return QTestResult::expectFail(dataIndex, qstrdup(comment), mode, file, line);
2245 void QTest::qWarn(const char *message, const char *file, int line)
2247 QTestLog::warn(message, file, line);
2251 Ignores messages created by qDebug() or qWarning(). If the \a message
2252 with the corresponding \a type is outputted, it will be removed from the
2253 test log. If the test finished and the \a message was not outputted,
2254 a test failure is appended to the test log.
2256 \b {Note:} Invoking this function will only ignore one message.
2257 If the message you want to ignore is outputted twice, you have to
2258 call ignoreMessage() twice, too.
2261 \snippet code/src_qtestlib_qtestcase.cpp 19
2263 The example above tests that QDir::mkdir() outputs the right warning when invoked
2264 with an invalid file name.
2266 void QTest::ignoreMessage(QtMsgType type, const char *message)
2268 QTestLog::ignoreMessage(type, message);
2275 static inline bool isWindowsBuildDirectory(const QString &dirName)
2277 return dirName.compare(QStringLiteral("Debug"), Qt::CaseInsensitive) == 0
2278 || dirName.compare(QStringLiteral("Release"), Qt::CaseInsensitive) == 0;
2282 QString QTest::qFindTestData(const QString& base, const char *file, int line, const char *builddir)
2286 // Testdata priorities:
2288 // 1. relative to test binary.
2290 QDir binDirectory(QCoreApplication::applicationDirPath());
2291 if (binDirectory.exists(base)) {
2292 found = binDirectory.absoluteFilePath(base);
2295 // Windows: The executable is typically located in one of the
2296 // 'Release' or 'Debug' directories.
2297 else if (isWindowsBuildDirectory(binDirectory.dirName())
2298 && binDirectory.cdUp() && binDirectory.exists(base)) {
2299 found = binDirectory.absoluteFilePath(base);
2302 else if (QTestLog::verboseLevel() >= 2) {
2303 const QString candidate = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + QLatin1Char('/') + base);
2304 QTestLog::info(qPrintable(
2305 QString::fromLatin1("testdata %1 not found relative to test binary [%2]; "
2306 "checking next location").arg(base, candidate)),
2311 // 2. installed path.
2312 if (found.isEmpty()) {
2313 const char *testObjectName = QTestResult::currentTestObjectName();
2314 if (testObjectName) {
2315 QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
2316 QString candidate = QString::fromLatin1("%1/%2/%3")
2317 .arg(testsPath, QFile::decodeName(testObjectName).toLower(), base);
2318 if (QFileInfo(candidate).exists()) {
2321 else if (QTestLog::verboseLevel() >= 2) {
2322 QTestLog::info(qPrintable(
2323 QString::fromLatin1("testdata %1 not found in tests install path [%2]; "
2324 "checking next location")
2325 .arg(base, QDir::toNativeSeparators(candidate))),
2331 // 3. relative to test source.
2332 if (found.isEmpty()) {
2333 // srcdir is the directory containing the calling source file.
2334 QFileInfo srcdir = QFileInfo(QFile::decodeName(file)).path();
2336 // If the srcdir is relative, that means it is relative to the current working
2337 // directory of the compiler at compile time, which should be passed in as `builddir'.
2338 if (!srcdir.isAbsolute() && builddir) {
2339 srcdir.setFile(QFile::decodeName(builddir) + QLatin1String("/") + srcdir.filePath());
2342 QString candidate = QString::fromLatin1("%1/%2").arg(srcdir.canonicalFilePath(), base);
2343 if (QFileInfo(candidate).exists()) {
2346 else if (QTestLog::verboseLevel() >= 2) {
2347 QTestLog::info(qPrintable(
2348 QString::fromLatin1("testdata %1 not found relative to source path [%2]")
2349 .arg(base, QDir::toNativeSeparators(candidate))),
2354 if (found.isEmpty()) {
2355 QTest::qWarn(qPrintable(
2356 QString::fromLatin1("testdata %1 could not be located!").arg(base)),
2359 else if (QTestLog::verboseLevel() >= 1) {
2360 QTestLog::info(qPrintable(
2361 QString::fromLatin1("testdata %1 was located at %2").arg(base, QDir::toNativeSeparators(found))),
2370 QString QTest::qFindTestData(const char *base, const char *file, int line, const char *builddir)
2372 return qFindTestData(QFile::decodeName(base), file, line, builddir);
2377 void *QTest::qData(const char *tagName, int typeId)
2379 return fetchData(QTestResult::currentTestData(), tagName, typeId);
2384 void *QTest::qGlobalData(const char *tagName, int typeId)
2386 return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
2391 void *QTest::qElementData(const char *tagName, int metaTypeId)
2393 QTEST_ASSERT(tagName);
2394 QTestData *data = QTestResult::currentTestData();
2396 QTEST_ASSERT(data->parent());
2398 int idx = data->parent()->indexOf(tagName);
2399 QTEST_ASSERT(idx != -1);
2400 QTEST_ASSERT(data->parent()->elementTypeId(idx) == metaTypeId);
2402 return data->data(data->parent()->indexOf(tagName));
2407 void QTest::addColumnInternal(int id, const char *name)
2409 QTestTable *tbl = QTestTable::currentTestTable();
2410 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
2412 tbl->addColumn(id, name);
2416 Appends a new row to the current test data. \a dataTag is the name of
2417 the testdata that will appear in the test output. Returns a QTestData reference
2418 that can be used to stream in data.
2421 \snippet code/src_qtestlib_qtestcase.cpp 20
2423 \b {Note:} This macro can only be used in a test's data function
2424 that is invoked by the test framework.
2426 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2427 a more extensive example.
2429 \sa addColumn(), QFETCH()
2431 QTestData &QTest::newRow(const char *dataTag)
2433 QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null");
2434 QTestTable *tbl = QTestTable::currentTestTable();
2435 QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot.");
2436 QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows.");
2438 return *tbl->newData(dataTag);
2441 /*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
2443 Adds a column with type \c{T} to the current test data.
2444 \a name is the name of the column. \a dummy is a workaround
2445 for buggy compilers and can be ignored.
2447 To populate the column with values, newRow() can be used. Use
2448 \l QFETCH() to fetch the data in the actual test.
2451 \snippet code/src_qtestlib_qtestcase.cpp 21
2453 To add custom types to the testdata, the type must be registered with
2454 QMetaType via \l Q_DECLARE_METATYPE().
2456 \b {Note:} This macro can only be used in a test's data function
2457 that is invoked by the test framework.
2459 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2460 a more extensive example.
2462 \sa QTest::newRow(), QFETCH(), QMetaType
2466 Returns the name of the test function that is currently executed.
2470 \snippet code/src_qtestlib_qtestcase.cpp 22
2472 const char *QTest::currentTestFunction()
2474 return QTestResult::currentTestFunction();
2478 Returns the name of the current test data. If the test doesn't
2479 have any assigned testdata, the function returns 0.
2481 const char *QTest::currentDataTag()
2483 return QTestResult::currentDataTag();
2487 Returns true if the current test function failed, otherwise false.
2489 bool QTest::currentTestFailed()
2491 return QTestResult::currentTestFailed();
2495 Sleeps for \a ms milliseconds, blocking execution of the
2496 test. qSleep() will not do any event processing and leave your test
2497 unresponsive. Network communication might time out while
2498 sleeping. Use \l qWait() to do non-blocking sleeping.
2500 \a ms must be greater than 0.
2502 \b {Note:} The qSleep() function calls either \c nanosleep() on
2503 unix or \c Sleep() on windows, so the accuracy of time spent in
2504 qSleep() depends on the operating system.
2507 \snippet code/src_qtestlib_qtestcase.cpp 23
2511 void QTest::qSleep(int ms)
2513 QTEST_ASSERT(ms > 0);
2518 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
2519 nanosleep(&ts, NULL);
2525 QObject *QTest::testObject()
2527 return currentTestObject;
2531 This function is called by various specializations of QTest::qCompare
2532 to decide whether to report a failure and to produce verbose test output.
2534 The failureMsg parameter can be null, in which case a default message
2535 will be output if the compare fails. If the compare succeeds, failureMsg
2538 If the caller has already passed a failure message showing the compared
2539 values, or if those values cannot be stringified, val1 and val2 can be null.
2541 bool QTest::compare_helper(bool success, const char *failureMsg,
2542 char *val1, char *val2,
2543 const char *actual, const char *expected,
2544 const char *file, int line)
2546 return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
2549 /*! \fn bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
2552 bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected,
2553 const char *file, int line)
2555 return compare_helper(qFuzzyCompare(t1, t2), "Compared floats are not the same (fuzzy compare)",
2556 toString(t1), toString(t2), actual, expected, file, line);
2559 /*! \fn bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
2562 bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected,
2563 const char *file, int line)
2565 return compare_helper(qFuzzyCompare(t1, t2), "Compared doubles are not the same (fuzzy compare)",
2566 toString(t1), toString(t2), actual, expected, file, line);
2569 #define TO_STRING_IMPL(TYPE, FORMAT) \
2570 template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
2572 char *msg = new char[128]; \
2573 qsnprintf(msg, 128, #FORMAT, t); \
2577 TO_STRING_IMPL(short, %hd)
2578 TO_STRING_IMPL(ushort, %hu)
2579 TO_STRING_IMPL(int, %d)
2580 TO_STRING_IMPL(uint, %u)
2581 TO_STRING_IMPL(long, %ld)
2582 TO_STRING_IMPL(ulong, %lu)
2583 #if defined(Q_OS_WIN)
2584 TO_STRING_IMPL(qint64, %I64d)
2585 TO_STRING_IMPL(quint64, %I64u)
2587 TO_STRING_IMPL(qint64, %lld)
2588 TO_STRING_IMPL(quint64, %llu)
2590 TO_STRING_IMPL(bool, %d)
2591 TO_STRING_IMPL(char, %c)
2592 TO_STRING_IMPL(float, %g)
2593 TO_STRING_IMPL(double, %lg)
2597 char *QTest::toString(const char *str)
2601 char *msg = new char[strlen(str) + 1];
2602 return qstrcpy(msg, str);
2607 char *QTest::toString(const void *p)
2609 char *msg = new char[128];
2610 qsnprintf(msg, 128, "%p", p);
2616 bool QTest::compare_string_helper(const char *t1, const char *t2, const char *actual,
2617 const char *expected, const char *file, int line)
2619 return compare_helper(qstrcmp(t1, t2) == 0, "Compared strings are not the same",
2620 toString(t1), toString(t2), actual, expected, file, line);
2623 /*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
2627 /*! \fn bool QTest::qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
2632 /*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
2636 /*! \fn bool QTest::qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line)
2640 /*! \fn bool QTest::qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, const char *file, int line)
2644 /*! \fn bool QTest::qCompare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2648 /*! \fn bool QTest::qCompare(const T *t1, const T *t2, const char *actual, const char *expected, const char *file, int line)
2652 /*! \fn bool QTest::qCompare(T *t1, T *t2, const char *actual, const char *expected, const char *file, int line)
2656 /*! \fn bool QTest::qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected, const char *file, int line)
2660 /*! \fn bool QTest::qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected, const char *file, int line)
2664 /*! \fn bool QTest::qCompare(const char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2668 /*! \fn bool QTest::qCompare(char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2672 /*! \fn bool QTest::qCompare(char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2676 /*! \fn bool QTest::qCompare(const char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2680 /*! \fn bool QTest::qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
2684 /*! \fn bool QTest::qCompare(QLatin1String const &t1, QString const &t2, const char *actual, const char *expected, const char *file, int line)
2688 /*! \fn bool QTest::qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected, const char *file, int line)
2692 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2696 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2700 /*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2704 /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
2708 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, QString text, Qt::KeyboardModifiers modifier, int delay=-1)
2712 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
2716 /*! \fn void QTest::simulateEvent(QWidget *widget, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)