1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtTest module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
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 \bold {Note:} This macro can only be used in a test function that is invoked
113 by the test framework.
116 \snippet doc/src/snippets/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 doc/src/snippets/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 doc/src/snippets/code/src_qtestlib_qtestcase.cpp 2
165 \sa QVERIFY(), QTRY_COMPARE(), QTest::toString()
168 /*! \macro QTRY_VERIFY_WITH_TIMEOUT(condition, timeout)
172 The QTRY_VERIFY_WITH_TIMEOUT() macro is similar to QVERIFY(), but checks the \a condition
173 repeatedly, until either the condition becomes true or the \a timeout is
174 reached. Between each evaluation, events will be processed. If the timeout
175 is reached, a failure is recorded in the test log and the test won't be
178 \note This macro can only be used in a test function that is invoked
179 by the test framework.
181 \sa QTRY_VERIFY(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
185 /*! \macro QTRY_VERIFY(condition)
189 Invokes QTRY_VERIFY_WITH_TIMEOUT() with a timeout of five seconds.
191 \note This macro can only be used in a test function that is invoked
192 by the test framework.
194 \sa QTRY_VERIFY_WITH_TIMEOUT(), QVERIFY(), QCOMPARE(), QTRY_COMPARE()
197 /*! \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)
217 Invokes QTRY_COMPARE_WITH_TIMEOUT() with a timeout of five seconds.
219 \note This macro can only be used in a test function that is invoked
220 by the test framework.
222 \sa QTRY_COMPARE_WITH_TIMEOUT(), QCOMPARE(), QVERIFY(), QTRY_VERIFY()
225 /*! \macro QFETCH(type, name)
229 The fetch macro creates a local variable named \a name with the type \a type
230 on the stack. \a name has to match the element name from the test's data.
231 If no such element exists, the test will assert.
233 Assuming a test has the following data:
235 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 3
237 The test data has two elements, a QString called \c aString and an integer
238 called \c expected. To fetch these values in the actual test:
240 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 4
242 \c aString and \c expected are variables on the stack that are initialized with
243 the current test data.
245 \bold {Note:} This macro can only be used in a test function that is invoked
246 by the test framework. The test function must have a _data function.
249 /*! \macro QWARN(message)
254 Appends \a message as a warning to the test log. This macro can be used anywhere
258 /*! \macro QFAIL(message)
262 This macro can be used to force a test failure. The test stops
263 executing and the failure \a message is appended to the test log.
265 \bold {Note:} This macro can only be used in a test function that is invoked
266 by the test framework.
270 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 5
273 /*! \macro QTEST(actual, testElement)
277 QTEST() is a convenience macro for \l QCOMPARE() that compares
278 the value \a actual with the element \a testElement from the test's data.
279 If there is no such element, the test asserts.
281 Apart from that, QTEST() behaves exactly as \l QCOMPARE().
285 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 6
289 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 7
294 /*! \macro QSKIP(description)
298 If called from a test function, the QSKIP() macro stops execution of the test
299 without adding a failure to the test log. You can use it to skip tests that
300 wouldn't make sense in the current configuration. The text \a description is
301 appended to the test log and should contain an explanation of why the test
302 couldn't be executed.
304 If the test is data-driven, each call to QSKIP() will skip only the current
305 row of test data, so an unconditional call to QSKIP will produce one skip
306 message in the test log for each row of test data.
308 If called from an _data function, the QSKIP() macro will stop execution of
309 the _data function and will prevent execution of the associated test
312 If called from initTestCase() or initTestCase_data(), the QSKIP() macro will
313 skip all test and _data functions.
315 \bold {Note:} This macro can only be used in a test function or _data
316 function that is invoked by the test framework.
319 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 8
322 /*! \macro QEXPECT_FAIL(dataIndex, comment, mode)
326 The QEXPECT_FAIL() macro marks the next \l QCOMPARE() or \l QVERIFY() as an
327 expected failure. Instead of adding a failure to the test log, an expected
328 failure will be reported.
330 If a \l QVERIFY() or \l QCOMPARE() is marked as an expected failure,
331 but passes instead, an unexpected pass (XPASS) is written to the test log.
333 The parameter \a dataIndex describes for which entry in the test data the
334 failure is expected. Pass an empty string (\c{""}) if the failure
335 is expected for all entries or if no test data exists.
337 \a comment will be appended to the test log for the expected failure.
339 \a mode is a \l QTest::TestFailMode and sets whether the test should
340 continue to execute or not.
342 \bold {Note:} This macro can only be used in a test function that is invoked
343 by the test framework.
346 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 9
348 In the example above, an expected fail will be written into the test output
349 if the variable \c i is not 42. If the variable \c i is 42, an unexpected pass
350 is written instead. The QEXPECT_FAIL() has no influence on the second QCOMPARE()
351 statement in the example.
354 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 10
356 The above testfunction will not continue executing for the test data
359 \sa QTest::TestFailMode, QVERIFY(), QCOMPARE()
362 /*! \macro QFINDTESTDATA(filename)
366 Returns a QString for the testdata file referred to by \a filename, or an
367 empty QString if the testdata file could not be found.
369 This macro allows the test to load data from an external file without
370 hardcoding an absolute filename into the test, or using relative paths
371 which may be error prone.
373 The returned path will be the first path from the following list which
374 resolves to an existing file or directory:
377 \o \a filename relative to QCoreApplication::applicationDirPath()
378 (only if a QCoreApplication or QApplication object has been created).
379 \o \a filename relative to the test's standard install directory
380 (QLibraryInfo::TestsPath with the lowercased testcase name appended).
381 \o \a filename relative to the directory containing the source file from which
382 QFINDTESTDATA is invoked.
385 If the named file/directory does not exist at any of these locations,
386 a warning is printed to the test log.
388 For example, in this code:
389 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 26
391 The testdata file will be resolved as the first existing file from:
394 \o \c{/home/user/build/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
395 \o \c{/usr/local/Qt-5.0.0/tests/tst_myxmlparser/testxml/simple1.xml}
396 \o \c{/home/user/sources/myxmlparser/tests/tst_myxmlparser/testxml/simple1.xml}
399 This allows the test to find its testdata regardless of whether the
400 test has been installed, and regardless of whether the test's build tree
401 is equal to the test's source tree.
403 \bold {Note:} reliable detection of testdata from the source directory requires
404 either that qmake is used, or the \c{QT_TESTCASE_BUILDDIR} macro is defined to
405 point to the working directory from which the compiler is invoked, or only
406 absolute paths to the source files are passed to the compiler. Otherwise, the
407 absolute path of the source directory cannot be determined.
410 /*! \macro QTEST_MAIN(TestClass)
414 Implements a main() function that instantiates an application object and
415 the \a TestClass, and executes all tests in the order they were defined.
416 Use this macro to build stand-alone executables.
418 If \c QT_WIDGETS_LIB is defined, the application object will be a QApplication,
419 if \c QT_GUI_LIB is defined, the application object will be a QGuiApplication,
420 otherwise it will be a QCoreApplication. If qmake is used and the configuration
421 includes \c{QT += widgets}, then \c QT_WIDGETS_LIB will be defined automatically.
422 Similarly, if qmake is used and the configuration includes \c{QT += gui}, then
423 \c QT_GUI_LIB will be defined automatically.
425 \bold {Note:} On platforms that have keypad navigation enabled by default,
426 this macro will forcefully disable it if \c QT_WIDGETS_LIB is defined. This is done
427 to simplify the usage of key events when writing autotests. If you wish to write a
428 test case that uses keypad navigation, you should enable it either in the
429 \c {initTestCase()} or \c {init()} functions of your test case by calling
430 \l {QApplication::setNavigationMode()}.
433 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 11
435 \sa QTEST_APPLESS_MAIN(), QTEST_GUILESS_MAIN(), QTest::qExec(),
436 QApplication::setNavigationMode()
439 /*! \macro QTEST_APPLESS_MAIN(TestClass)
443 Implements a main() function that executes all tests in \a TestClass.
445 Behaves like \l QTEST_MAIN(), but doesn't instantiate a QApplication
446 object. Use this macro for really simple stand-alone non-GUI tests.
451 /*! \macro QTEST_GUILESS_MAIN(TestClass)
455 Implements a main() function that instantiates a QCoreApplication object
456 and the \a TestClass, and executes all tests in the order they were
457 defined. Use this macro to build stand-alone executables.
459 Behaves like \l QTEST_MAIN(), but instantiates a QCoreApplication instead
460 of the QApplication object. Use this macro if your test case doesn't need
461 functionality offered by QApplication, but the event loop is still necessary.
471 This macro is used to measure the performance of code within a test.
472 The code to be benchmarked is contained within a code block following
477 \snippet examples/qtestlib/tutorial5/benchmarking.cpp 0
479 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
480 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
484 \macro QBENCHMARK_ONCE
489 \brief The QBENCHMARK_ONCE macro is for measuring performance of a
490 code block by running it once.
492 This macro is used to measure the performance of code within a test.
493 The code to be benchmarked is contained within a code block following
496 Unlike QBENCHMARK, the contents of the contained code block is only run
497 once. The elapsed time will be reported as "0" if it's to short to
498 be measured by the selected backend. (Use)
500 \sa {QTestLib Manual#Creating a Benchmark}{Creating a Benchmark},
501 {Chapter 5: Writing a Benchmark}{Writing a Benchmark}
504 /*! \enum QTest::TestFailMode
506 This enum describes the modes for handling an expected failure of the
507 \l QVERIFY() or \l QCOMPARE() macros.
509 \value Abort Aborts the execution of the test. Use this mode when it
510 doesn't make sense to execute the test any further after the
513 \value Continue Continues execution of the test after the expected failure.
518 /*! \enum QTest::KeyAction
520 This enum describes possible actions for key handling.
522 \value Press The key is pressed.
523 \value Release The key is released.
524 \value Click The key is clicked (pressed and released).
527 /*! \enum QTest::MouseAction
529 This enum describes possible actions for mouse handling.
531 \value MousePress A mouse button is pressed.
532 \value MouseRelease A mouse button is released.
533 \value MouseClick A mouse button is clicked (pressed and released).
534 \value MouseDClick A mouse button is double clicked (pressed and released twice).
535 \value MouseMove The mouse pointer has moved.
538 /*! \fn void QTest::keyClick(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
542 Simulates clicking of \a key with an optional \a modifier on a \a widget.
543 If \a delay is larger than 0, the test will wait for \a delay milliseconds
544 before clicking the key.
547 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 13
549 The example above simulates clicking \c a on \c myWidget without
550 any keyboard modifiers and without delay of the test.
552 \sa QTest::keyClicks()
555 /*! \fn void QTest::keyClick(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
557 Simulates clicking of \a key with an optional \a modifier on a \a widget.
558 If \a delay is larger than 0, the test will wait for \a delay milliseconds
559 before clicking the key.
562 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 14
564 The first example above simulates clicking the \c escape key on \c
565 myWidget without any keyboard modifiers and without delay. The
566 second example simulates clicking \c shift-escape on \c myWidget
567 following a 200 ms delay of the test.
569 \sa QTest::keyClicks()
572 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
574 Sends a Qt key event to \a widget with the given \a key and an associated \a action.
575 Optionally, a keyboard \a modifier can be specified, as well as a \a delay
576 (in milliseconds) of the test before sending the event.
579 /*! \fn void QTest::keyEvent(KeyAction action, QWidget *widget, char ascii, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
583 Sends a Qt key event to \a widget with the given key \a ascii 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.
589 /*! \fn void QTest::keyPress(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
591 Simulates pressing a \a key with an optional \a modifier on a \a widget. If \a delay
592 is larger than 0, the test will wait for \a delay milliseconds before pressing the key.
594 \bold {Note:} At some point you should release the key using \l keyRelease().
596 \sa QTest::keyRelease(), QTest::keyClick()
599 /*! \fn void QTest::keyPress(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
603 Simulates pressing a \a key with an optional \a modifier on a \a widget.
604 If \a delay is larger than 0, the test will wait for \a delay milliseconds
605 before pressing the key.
607 \bold {Note:} At some point you should release the key using \l keyRelease().
609 \sa QTest::keyRelease(), QTest::keyClick()
612 /*! \fn void QTest::keyRelease(QWidget *widget, Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
614 Simulates releasing a \a key with an optional \a modifier on a \a widget.
615 If \a delay is larger than 0, the test will wait for \a delay milliseconds
616 before releasing the key.
618 \sa QTest::keyPress(), QTest::keyClick()
621 /*! \fn void QTest::keyRelease(QWidget *widget, char key, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
625 Simulates releasing a \a key with an optional \a modifier on a \a widget.
626 If \a delay is larger than 0, the test will wait for \a delay milliseconds
627 before releasing the key.
629 \sa QTest::keyClick()
633 /*! \fn void QTest::keyClicks(QWidget *widget, const QString &sequence, Qt::KeyboardModifiers modifier = Qt::NoModifier, int delay=-1)
635 Simulates clicking a \a sequence of keys on a \a
636 widget. Optionally, a keyboard \a modifier can be specified as
637 well as a \a delay (in milliseconds) of the test before each key
641 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 15
643 The example above simulates clicking the sequence of keys
644 representing "hello world" on \c myWidget without any keyboard
645 modifiers and without delay of the test.
647 \sa QTest::keyClick()
650 /*! \fn void QTest::mousePress(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
652 Simulates pressing a mouse \a button with an optional \a modifier
653 on a \a widget. The position is defined by \a pos; the default
654 position is the center of the widget. If \a delay is specified,
655 the test will wait for the specified amount of milliseconds before
658 \sa QTest::mouseRelease(), QTest::mouseClick()
661 /*! \fn void QTest::mouseRelease(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
663 Simulates releasing a mouse \a button with an optional \a modifier
664 on a \a widget. The position of the release is defined by \a pos;
665 the default position is the center of the widget. If \a delay is
666 specified, the test will wait for the specified amount of
667 milliseconds before releasing the button.
669 \sa QTest::mousePress(), QTest::mouseClick()
672 /*! \fn void QTest::mouseClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
674 Simulates clicking a mouse \a button with an optional \a modifier
675 on a \a widget. The position of the click is defined by \a pos;
676 the default position is the center of the widget. If \a delay is
677 specified, the test will wait for the specified amount of
678 milliseconds before pressing and before releasing the button.
680 \sa QTest::mousePress(), QTest::mouseRelease()
683 /*! \fn void QTest::mouseDClick(QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers modifier = 0, QPoint pos = QPoint(), int delay=-1)
685 Simulates double clicking a mouse \a button with an optional \a
686 modifier on a \a widget. The position of the click is defined by
687 \a pos; the default position is the center of the widget. If \a
688 delay is specified, the test will wait for the specified amount of
689 milliseconds before each press and release.
691 \sa QTest::mouseClick()
694 /*! \fn void QTest::mouseMove(QWidget *widget, QPoint pos = QPoint(), int delay=-1)
696 Moves the mouse pointer to a \a widget. If \a pos is not
697 specified, the mouse pointer moves to the center of the widget. If
698 a \a delay (in milliseconds) is given, the test will wait before
699 moving the mouse pointer.
703 \fn char *QTest::toString(const T &value)
705 Returns a textual representation of \a value. This function is used by
706 \l QCOMPARE() to output verbose information in case of a test failure.
708 You can add specializations of this function to your test to enable
711 \bold {Note:} The caller of toString() must delete the returned data
712 using \c{delete[]}. Your implementation should return a string
713 created with \c{new[]} or qstrdup().
717 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 16
719 The example above defines a toString() specialization for a class
720 called \c MyPoint. Whenever a comparison of two instances of \c
721 MyPoint fails, \l QCOMPARE() will call this function to output the
722 contents of \c MyPoint to the test log.
728 \fn char *QTest::toString(const QLatin1String &string)
731 Returns a textual representation of the given \a string.
735 \fn char *QTest::toString(const QString &string)
738 Returns a textual representation of the given \a string.
742 \fn char *QTest::toString(const QByteArray &ba)
745 Returns a textual representation of the byte array \a ba.
747 \sa QTest::toHexRepresentation()
751 \fn char *QTest::toString(const QTime &time)
754 Returns a textual representation of the given \a time.
758 \fn char *QTest::toString(const QDate &date)
761 Returns a textual representation of the given \a date.
765 \fn char *QTest::toString(const QDateTime &dateTime)
768 Returns a textual representation of the date and time specified by
773 \fn char *QTest::toString(const QChar &character)
776 Returns a textual representation of the given \a character.
780 \fn char *QTest::toString(const QPoint &point)
783 Returns a textual representation of the given \a point.
787 \fn char *QTest::toString(const QSize &size)
790 Returns a textual representation of the given \a size.
794 \fn char *QTest::toString(const QRect &rectangle)
797 Returns a textual representation of the given \a rectangle.
801 \fn char *QTest::toString(const QUrl &url)
805 Returns a textual representation of the given \a url.
809 \fn char *QTest::toString(const QPointF &point)
812 Returns a textual representation of the given \a point.
816 \fn char *QTest::toString(const QSizeF &size)
819 Returns a textual representation of the given \a size.
823 \fn char *QTest::toString(const QRectF &rectangle)
826 Returns a textual representation of the given \a rectangle.
830 \fn char *QTest::toString(const QVariant &variant)
833 Returns a textual representation of the given \a variant.
836 /*! \fn void QTest::qWait(int ms)
838 Waits for \a ms milliseconds. While waiting, events will be processed and
839 your test will stay responsive to user interface events or network communication.
842 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 17
844 The code above will wait until the network server is responding for a
845 maximum of about 12.5 seconds.
850 /*! \fn bool QTest::qWaitForWindowShown(QWidget *window)
853 Waits until the \a window is shown in the screen. This is mainly useful for
854 asynchronous systems like X11, where a window will be mapped to screen some
855 time after being asked to show itself on the screen. Returns true.
858 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 24
862 \class QTest::QTouchEventSequence
866 \brief The QTouchEventSequence class is used to simulate a sequence of touch events.
868 To simulate a sequence of touch events on a specific device for a widget, call
869 QTest::touchEvent to create a QTouchEventSequence instance. Add touch events to
870 the sequence by calling press(), move(), release() and stationary(), and let the
871 instance run out of scope to commit the sequence to the event system.
874 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 25
878 \fn QTest::QTouchEventSequence::~QTouchEventSequence()
880 Commits this sequence of touch events and frees allocated resources.
884 \fn QTouchEventSequence &QTest::QTouchEventSequence::press(int touchId, const QPoint &pt, QWidget *widget)
886 Adds a press event for touchpoint \a touchId at position \a pt to this sequence and returns
887 a reference to this QTouchEventSequence.
889 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
890 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
892 Simulates that the user pressed the touch screen or pad with the finger identified by \a touchId.
896 \fn QTouchEventSequence &QTest::QTouchEventSequence::move(int touchId, const QPoint &pt, QWidget *widget)
898 Adds a move event for touchpoint \a touchId at position \a pt to this sequence and returns
899 a reference to this QTouchEventSequence.
901 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
902 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
904 Simulates that the user moved the finger identified by \a touchId.
908 \fn QTouchEventSequence &QTest::QTouchEventSequence::release(int touchId, const QPoint &pt, QWidget *widget)
910 Adds a release event for touchpoint \a touchId at position \a pt to this sequence and returns
911 a reference to this QTouchEventSequence.
913 The position \a pt is interpreted as relative to \a widget. If \a widget is the null pointer, then
914 \a pt is interpreted as relative to the widget provided when instantiating this QTouchEventSequence.
916 Simulates that the user lifted the finger identified by \a touchId.
920 \fn QTouchEventSequence &QTest::QTouchEventSequence::stationary(int touchId)
922 Adds a stationary event for touchpoint \a touchId to this sequence and returns
923 a reference to this QTouchEventSequence.
925 Simulates that the user did not move the finger identified by \a touchId.
929 \fn QTouchEventSequence QTest::touchEvent(QWidget *widget, QTouchEvent::DeviceType deviceType)
931 Creates and returns a QTouchEventSequence for the device \a deviceType to
932 simulate events for \a widget.
934 When adding touch events to the sequence, \a widget will also be used to translate
935 the position provided to screen coordinates, unless another widget is provided in the
936 respective calls to press(), move() etc.
938 The touch events are committed to the event system when the destructor of the
939 QTouchEventSequence is called (ie when the object returned runs out of scope).
942 static bool installCoverageTool(const char * appname, const char * testname)
944 #ifdef __COVERAGESCANNER__
945 if (!qgetenv("QT_TESTCOCOON_ACTIVE").isEmpty())
947 // Set environment variable QT_TESTCOCOON_ACTIVE to prevent an eventual subtest from
948 // being considered as a stand-alone test regarding the coverage analysis.
949 qputenv("QT_TESTCOCOON_ACTIVE", "1");
951 // Install Coverage Tool
952 __coveragescanner_install(appname);
953 __coveragescanner_testname(testname);
954 __coveragescanner_clear();
965 static QObject *currentTestObject = 0;
969 TestFunction() : function_(-1), data_(0) {}
970 void set(int function, char *data) { function_ = function; data_ = data; }
971 char *data() const { return data_; }
972 int function() const { return function_; }
973 ~TestFunction() { delete[] data_; }
979 * Contains the list of test functions that was supplied
980 * on the command line, if any. Hence, if not empty,
981 * those functions should be run instead of
982 * all appearing in the test case.
984 static TestFunction * testFuncs = 0;
985 static int testFuncCount = 0;
987 /** Don't leak testFuncs on exit even on error */
988 static struct TestFuncCleanup
997 ~TestFuncCleanup() { cleanup(); }
1000 static int keyDelay = -1;
1001 static int mouseDelay = -1;
1002 static int eventDelay = -1;
1003 #if defined(Q_OS_UNIX)
1004 static bool noCrashHandler = false;
1008 Invoke a method of the object without generating warning if the method does not exist
1010 static void invokeMethod(QObject *obj, const char *methodName)
1012 const QMetaObject *metaObject = obj->metaObject();
1013 int funcIndex = metaObject->indexOfMethod(methodName);
1014 if (funcIndex >= 0) {
1015 QMetaMethod method = metaObject->method(funcIndex);
1016 method.invoke(obj, Qt::DirectConnection);
1020 int defaultEventDelay()
1022 if (eventDelay == -1) {
1023 if (!qgetenv("QTEST_EVENT_DELAY").isEmpty())
1024 eventDelay = atoi(qgetenv("QTEST_EVENT_DELAY"));
1031 int Q_TESTLIB_EXPORT defaultMouseDelay()
1033 if (mouseDelay == -1) {
1034 if (!qgetenv("QTEST_MOUSEEVENT_DELAY").isEmpty())
1035 mouseDelay = atoi(qgetenv("QTEST_MOUSEEVENT_DELAY"));
1037 mouseDelay = defaultEventDelay();
1042 int Q_TESTLIB_EXPORT defaultKeyDelay()
1044 if (keyDelay == -1) {
1045 if (!qgetenv("QTEST_KEYEVENT_DELAY").isEmpty())
1046 keyDelay = atoi(qgetenv("QTEST_KEYEVENT_DELAY").constData());
1048 keyDelay = defaultEventDelay();
1053 static bool isValidSlot(const QMetaMethod &sl)
1055 if (sl.access() != QMetaMethod::Private || !sl.parameterTypes().isEmpty()
1056 || qstrlen(sl.typeName()) || sl.methodType() != QMetaMethod::Slot)
1058 const char *sig = sl.signature();
1059 int len = qstrlen(sig);
1062 if (sig[len - 2] != '(' || sig[len - 1] != ')')
1064 if (len > 7 && strcmp(sig + (len - 7), "_data()") == 0)
1066 if (strcmp(sig, "initTestCase()") == 0 || strcmp(sig, "cleanupTestCase()") == 0
1067 || strcmp(sig, "cleanup()") == 0 || strcmp(sig, "init()") == 0)
1072 Q_TESTLIB_EXPORT bool printAvailableFunctions = false;
1073 Q_TESTLIB_EXPORT QStringList testFunctions;
1074 Q_TESTLIB_EXPORT QStringList testTags;
1076 static void qPrintTestSlots(FILE *stream)
1078 for (int i = 0; i < QTest::currentTestObject->metaObject()->methodCount(); ++i) {
1079 QMetaMethod sl = QTest::currentTestObject->metaObject()->method(i);
1080 if (isValidSlot(sl))
1081 fprintf(stream, "%s\n", sl.signature());
1085 static void qPrintDataTags(FILE *stream)
1087 // Avoid invoking the actual test functions, and also avoid printing irrelevant output:
1088 QTestLog::setPrintAvailableTagsMode();
1090 // Get global data tags:
1091 QTestTable::globalTestTable();
1092 invokeMethod(QTest::currentTestObject, "initTestCase_data()");
1093 const QTestTable *gTable = QTestTable::globalTestTable();
1095 const QMetaObject *currTestMetaObj = QTest::currentTestObject->metaObject();
1097 // Process test functions:
1098 for (int i = 0; i < currTestMetaObj->methodCount(); ++i) {
1099 QMetaMethod tf = currTestMetaObj->method(i);
1101 if (isValidSlot(tf)) {
1103 // Retrieve local tags:
1104 QStringList localTags;
1106 char *slot = qstrdup(tf.signature());
1107 slot[strlen(slot) - 2] = '\0';
1109 member.resize(qstrlen(slot) + qstrlen("_data()") + 1);
1110 qsnprintf(member.data(), member.size(), "%s_data()", slot);
1111 invokeMethod(QTest::currentTestObject, member.constData());
1112 for (int j = 0; j < table.dataCount(); ++j)
1113 localTags << QLatin1String(table.testData(j)->dataTag());
1115 // Print all tag combinations:
1116 if (gTable->dataCount() == 0) {
1117 if (localTags.count() == 0) {
1118 // No tags at all, so just print the test function:
1119 fprintf(stream, "%s %s\n", currTestMetaObj->className(), slot);
1121 // Only local tags, so print each of them:
1122 for (int k = 0; k < localTags.size(); ++k)
1124 stream, "%s %s %s\n",
1125 currTestMetaObj->className(), slot, localTags.at(k).toLatin1().data());
1128 for (int j = 0; j < gTable->dataCount(); ++j) {
1129 if (localTags.count() == 0) {
1130 // Only global tags, so print the current one:
1132 stream, "%s %s __global__ %s\n",
1133 currTestMetaObj->className(), slot, gTable->testData(j)->dataTag());
1135 // Local and global tags, so print each of the local ones and
1136 // the current global one:
1137 for (int k = 0; k < localTags.size(); ++k)
1139 stream, "%s %s %s __global__ %s\n", currTestMetaObj->className(), slot,
1140 localTags.at(k).toLatin1().data(), gTable->testData(j)->dataTag());
1150 static int qToInt(char *str)
1153 int l = (int)strtol(str, &pEnd, 10);
1155 fprintf(stderr, "Invalid numeric parameter: '%s'\n", str);
1161 Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml)
1163 QTestLog::LogMode logFormat = QTestLog::Plain;
1164 const char *logFilename = 0;
1166 const char *testOptions =
1167 " New-style logging options:\n"
1168 " -o filename,format : Output results to file in the specified format\n"
1169 " Use - to output to stdout\n"
1170 " Valid formats are:\n"
1171 " txt : Plain text\n"
1172 " xunitxml : XML XUnit document\n"
1173 " xml : XML document\n"
1174 " lightxml : A stream of XML tags\n"
1176 " *** Multiple loggers can be specified, but at most one can log to stdout.\n"
1178 " Old-style logging options:\n"
1179 " -o filename : Write the output into file\n"
1180 " -txt : Output results in Plain Text\n"
1181 " -xunitxml : Output results as XML XUnit document\n"
1182 " -xml : Output results as XML document\n"
1183 " -lightxml : Output results as stream of XML tags\n"
1185 " *** If no output file is specified, stdout is assumed.\n"
1186 " *** If no output format is specified, -txt is assumed.\n"
1188 " Detail options:\n"
1189 " -silent : Only outputs warnings and failures\n"
1190 " -v1 : Print enter messages for each testfunction\n"
1191 " -v2 : Also print out each QVERIFY/QCOMPARE/QTEST\n"
1192 " -vs : Print every signal emitted\n"
1194 " Testing options:\n"
1195 " -functions : Returns a list of current testfunctions\n"
1196 " -datatags : Returns a list of current data tags.\n"
1197 " A global data tag is preceded by ' __global__ '.\n"
1198 " -eventdelay ms : Set default delay for mouse and keyboard simulation to ms milliseconds\n"
1199 " -keydelay ms : Set default delay for keyboard simulation to ms milliseconds\n"
1200 " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n"
1201 " -maxwarnings n : Sets the maximum amount of messages to output.\n"
1202 " 0 means unlimited, default: 2000\n"
1203 #if defined(Q_OS_UNIX)
1204 " -nocrashhandler : Disables the crash handler\n"
1207 " Benchmarking options:\n"
1208 #ifdef QTESTLIB_USE_VALGRIND
1209 " -callgrind : Use callgrind to time benchmarks\n"
1211 #ifdef HAVE_TICK_COUNTER
1212 " -tickcounter : Use CPU tick counters to time benchmarks\n"
1214 " -eventcounter : Counts events received during benchmarks\n"
1215 " -minimumvalue n : Sets the minimum acceptable measurement value\n"
1216 " -iterations n : Sets the number of accumulation iterations.\n"
1217 " -median n : Sets the number of median iterations.\n"
1218 " -vb : Print out verbose benchmarking information.\n";
1220 for (int i = 1; i < argc; ++i) {
1221 if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0
1222 || strcmp(argv[i], "/?") == 0) {
1223 printf(" Usage: %s [options] [testfunction[:testdata]]...\n"
1224 " By default, all testfunctions will be run.\n\n"
1225 "%s", argv[0], testOptions);
1229 " QmlTest options:\n"
1230 " -import dir : Specify an import directory.\n"
1231 " -input dir/file : Specify the root directory for test cases or a single test case file.\n"
1232 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1233 " -translation file : Specify the translation file.\n"
1238 " -help : This help\n");
1240 } else if (strcmp(argv[i], "-functions") == 0) {
1242 QTest::printAvailableFunctions = true;
1244 qPrintTestSlots(stdout);
1247 } else if (strcmp(argv[i], "-datatags") == 0) {
1249 qPrintDataTags(stdout);
1252 } else if (strcmp(argv[i], "-txt") == 0) {
1253 logFormat = QTestLog::Plain;
1254 } else if (strcmp(argv[i], "-xunitxml") == 0) {
1255 logFormat = QTestLog::XunitXML;
1256 } else if (strcmp(argv[i], "-xml") == 0) {
1257 logFormat = QTestLog::XML;
1258 } else if (strcmp(argv[i], "-lightxml") == 0) {
1259 logFormat = QTestLog::LightXML;
1260 } else if (strcmp(argv[i], "-silent") == 0) {
1261 QTestLog::setVerboseLevel(-1);
1262 } else if (strcmp(argv[i], "-v1") == 0) {
1263 QTestLog::setVerboseLevel(1);
1264 } else if (strcmp(argv[i], "-v2") == 0) {
1265 QTestLog::setVerboseLevel(2);
1266 } else if (strcmp(argv[i], "-vs") == 0) {
1267 QSignalDumper::startDump();
1268 } else if (strcmp(argv[i], "-o") == 0) {
1269 if (i + 1 >= argc) {
1270 fprintf(stderr, "-o needs an extra parameter specifying the filename and optional format\n");
1274 // Do we have the old or new style -o option?
1275 char *filename = new char[strlen(argv[i])+1];
1276 char *format = new char[strlen(argv[i])+1];
1277 if (sscanf(argv[i], "%[^,],%s", filename, format) == 1) {
1279 logFilename = argv[i];
1282 if (strcmp(format, "txt") == 0)
1283 logFormat = QTestLog::Plain;
1284 else if (strcmp(format, "lightxml") == 0)
1285 logFormat = QTestLog::LightXML;
1286 else if (strcmp(format, "xml") == 0)
1287 logFormat = QTestLog::XML;
1288 else if (strcmp(format, "xunitxml") == 0)
1289 logFormat = QTestLog::XunitXML;
1291 fprintf(stderr, "output format must be one of txt, lightxml, xml or xunitxml\n");
1294 if (strcmp(filename, "-") == 0 && QTestLog::loggerUsingStdout()) {
1295 fprintf(stderr, "only one logger can log to stdout\n");
1298 QTestLog::addLogger(logFormat, filename);
1302 } else if (strcmp(argv[i], "-eventdelay") == 0) {
1303 if (i + 1 >= argc) {
1304 fprintf(stderr, "-eventdelay needs an extra parameter to indicate the delay(ms)\n");
1307 QTest::eventDelay = qToInt(argv[++i]);
1309 } else if (strcmp(argv[i], "-keydelay") == 0) {
1310 if (i + 1 >= argc) {
1311 fprintf(stderr, "-keydelay needs an extra parameter to indicate the delay(ms)\n");
1314 QTest::keyDelay = qToInt(argv[++i]);
1316 } else if (strcmp(argv[i], "-mousedelay") == 0) {
1317 if (i + 1 >= argc) {
1318 fprintf(stderr, "-mousedelay needs an extra parameter to indicate the delay(ms)\n");
1321 QTest::mouseDelay = qToInt(argv[++i]);
1323 } else if (strcmp(argv[i], "-maxwarnings") == 0) {
1324 if (i + 1 >= argc) {
1325 fprintf(stderr, "-maxwarnings needs an extra parameter with the amount of warnings\n");
1328 QTestLog::setMaxWarnings(qToInt(argv[++i]));
1330 #if defined(Q_OS_UNIX)
1331 } else if (strcmp(argv[i], "-nocrashhandler") == 0) {
1332 QTest::noCrashHandler = true;
1334 #ifdef QTESTLIB_USE_VALGRIND
1335 } else if (strcmp(argv[i], "-callgrind") == 0) {
1336 if (QBenchmarkValgrindUtils::haveValgrind())
1337 if (QFileInfo(QDir::currentPath()).isWritable()) {
1338 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindParentProcess);
1340 fprintf(stderr, "WARNING: Current directory not writable. Using the walltime measurer.\n");
1343 fprintf(stderr, "WARNING: Valgrind not found or too old. Make sure it is installed and in your path. "
1344 "Using the walltime measurer.\n");
1346 } else if (strcmp(argv[i], "-callgrindchild") == 0) { // "private" option
1347 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::CallgrindChildProcess);
1348 QBenchmarkGlobalData::current->callgrindOutFileBase =
1349 QBenchmarkValgrindUtils::outFileBase();
1351 #ifdef HAVE_TICK_COUNTER
1352 } else if (strcmp(argv[i], "-tickcounter") == 0) {
1353 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::TickCounter);
1355 } else if (strcmp(argv[i], "-eventcounter") == 0) {
1356 QBenchmarkGlobalData::current->setMode(QBenchmarkGlobalData::EventCounter);
1357 } else if (strcmp(argv[i], "-minimumvalue") == 0) {
1358 if (i + 1 >= argc) {
1359 fprintf(stderr, "-minimumvalue needs an extra parameter to indicate the minimum time(ms)\n");
1362 QBenchmarkGlobalData::current->walltimeMinimum = qToInt(argv[++i]);
1364 } else if (strcmp(argv[i], "-iterations") == 0) {
1365 if (i + 1 >= argc) {
1366 fprintf(stderr, "-iterations needs an extra parameter to indicate the number of iterations\n");
1369 QBenchmarkGlobalData::current->iterationCount = qToInt(argv[++i]);
1371 } else if (strcmp(argv[i], "-median") == 0) {
1372 if (i + 1 >= argc) {
1373 fprintf(stderr, "-median needs an extra parameter to indicate the number of median iterations\n");
1376 QBenchmarkGlobalData::current->medianIterationCount = qToInt(argv[++i]);
1379 } else if (strcmp(argv[i], "-vb") == 0) {
1380 QBenchmarkGlobalData::current->verboseOutput = true;
1381 } else if (argv[i][0] == '-') {
1382 fprintf(stderr, "Unknown option: '%s'\n\n%s", argv[i], testOptions);
1384 fprintf(stderr, "\nqmltest related options:\n"
1385 " -import : Specify an import directory.\n"
1386 " -input : Specify the root directory for test cases.\n"
1387 " -qtquick1 : Run with QtQuick 1 rather than QtQuick 2.\n"
1391 fprintf(stderr, "\n"
1392 " -help : This help\n");
1395 // We can't check the availability of test functions until
1396 // we load the QML files. So just store the data for now.
1399 for (offset = 0; *(argv[i]+offset); ++offset) {
1400 if (*(argv[i]+offset) == ':') {
1401 if (*(argv[i]+offset+1) == ':') {
1402 // "::" is used as a test name separator.
1403 // e.g. "ClickTests::test_click:row1".
1412 QTest::testFunctions += QString::fromLatin1(argv[i]);
1413 QTest::testTags += QString();
1415 QTest::testFunctions +=
1416 QString::fromLatin1(argv[i], colon);
1418 QString::fromLatin1(argv[i] + colon + 1);
1421 if (!QTest::testFuncs) {
1422 QTest::testFuncs = new QTest::TestFunction[512];
1426 char buf[512], *data=0;
1428 for (off = 0; *(argv[i]+off); ++off) {
1429 if (*(argv[i]+off) == ':') {
1435 data = qstrdup(argv[i]+colon+1);
1437 qsnprintf(buf, qMin(512, off + 1), "%s", argv[i]); // copy text before the ':' into buf
1438 qsnprintf(buf + off, qMin(512 - off, 3), "()"); // append "()"
1439 int idx = QTest::currentTestObject->metaObject()->indexOfMethod(buf);
1440 if (idx < 0 || !isValidSlot(QTest::currentTestObject->metaObject()->method(idx))) {
1441 fprintf(stderr, "Unknown testfunction: '%s'\n", buf);
1442 fprintf(stderr, "Available testfunctions:\n");
1443 qPrintTestSlots(stderr);
1446 testFuncs[testFuncCount].set(idx, data);
1448 QTEST_ASSERT(QTest::testFuncCount < 512);
1452 // If no loggers were created by the long version of the -o command-line
1453 // option, create a logger using whatever filename and format were
1454 // set using the old-style command-line options.
1455 if (QTestLog::loggerCount() == 0)
1456 QTestLog::addLogger(logFormat, logFilename);
1459 QBenchmarkResult qMedian(const QList<QBenchmarkResult> &container)
1461 const int count = container.count();
1463 return QBenchmarkResult();
1466 return container.at(0);
1468 QList<QBenchmarkResult> containerCopy = container;
1469 qSort(containerCopy);
1471 const int middle = count / 2;
1473 // ### handle even-sized containers here by doing an aritmetic mean of the two middle items.
1474 return containerCopy.at(middle);
1477 struct QTestDataSetter
1479 QTestDataSetter(QTestData *data)
1481 QTestResult::setCurrentTestData(data);
1485 QTestResult::setCurrentTestData(0);
1489 static void qInvokeTestMethodDataEntry(char *slot)
1491 /* Benchmarking: for each median iteration*/
1493 bool isBenchmark = false;
1494 int i = (QBenchmarkGlobalData::current->measurer->needsWarmupIteration()) ? -1 : 0;
1496 QList<QBenchmarkResult> results;
1498 QBenchmarkTestMethodData::current->beginDataRun();
1500 /* Benchmarking: for each accumulation iteration*/
1503 invokeMethod(QTest::currentTestObject, "init()");
1504 if (QTestResult::skipCurrentTest() || QTestResult::currentTestFailed())
1507 QBenchmarkTestMethodData::current->result = QBenchmarkResult();
1508 QBenchmarkTestMethodData::current->resultAccepted = false;
1510 QBenchmarkGlobalData::current->context.tag =
1512 QTestResult::currentDataTag()
1513 ? QTestResult::currentDataTag() : "");
1515 invokeOk = QMetaObject::invokeMethod(QTest::currentTestObject, slot,
1516 Qt::DirectConnection);
1518 QTestResult::addFailure("Unable to execute slot", __FILE__, __LINE__);
1520 isBenchmark = QBenchmarkTestMethodData::current->isBenchmark();
1522 QTestResult::finishedCurrentTestData();
1524 invokeMethod(QTest::currentTestObject, "cleanup()");
1526 // If the test isn't a benchmark, finalize the result after cleanup() has finished.
1528 QTestResult::finishedCurrentTestDataCleanup();
1530 // If this test method has a benchmark, repeat until all measurements are
1532 // The QBENCHMARK macro increases the number of iterations for each run until
1534 } while (invokeOk && isBenchmark
1535 && QBenchmarkTestMethodData::current->resultsAccepted() == false
1536 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1538 QBenchmarkTestMethodData::current->endDataRun();
1539 if (!QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed()) {
1540 if (i > -1) // iteration -1 is the warmup iteration.
1541 results.append(QBenchmarkTestMethodData::current->result);
1543 if (isBenchmark && QBenchmarkGlobalData::current->verboseOutput) {
1545 QTestLog::info(qPrintable(
1546 QString::fromLatin1("warmup stage result : %1")
1547 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1549 QTestLog::info(qPrintable(
1550 QString::fromLatin1("accumulation stage result: %1")
1551 .arg(QBenchmarkTestMethodData::current->result.value)), 0, 0);
1555 } while (isBenchmark
1556 && (++i < QBenchmarkGlobalData::current->adjustMedianIterationCount())
1557 && !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed());
1559 // If the test is a benchmark, finalize the result after all iterations have finished.
1561 bool testPassed = !QTestResult::skipCurrentTest() && !QTestResult::currentTestFailed();
1562 QTestResult::finishedCurrentTestDataCleanup();
1563 // Only report benchmark figures if the test passed
1564 if (testPassed && QBenchmarkTestMethodData::current->resultsAccepted())
1565 QTestLog::addBenchmarkResult(qMedian(results));
1572 Call slot_data(), init(), slot(), cleanup(), init(), slot(), cleanup(), ...
1573 If data is set then it is the only test that is performed
1575 If the function was successfully called, true is returned, otherwise
1578 static bool qInvokeTestMethod(const char *slotName, const char *data=0)
1580 QTEST_ASSERT(slotName);
1582 QBenchmarkTestMethodData benchmarkData;
1583 QBenchmarkTestMethodData::current = &benchmarkData;
1585 QBenchmarkGlobalData::current->context.slotName = QLatin1String(slotName);
1590 char *slot = qstrdup(slotName);
1591 slot[strlen(slot) - 2] = '\0';
1592 QTestResult::setCurrentTestFunction(slot);
1594 const QTestTable *gTable = QTestTable::globalTestTable();
1595 const int globalDataCount = gTable->dataCount();
1596 int curGlobalDataIndex = 0;
1598 /* For each test function that has a *_data() table/function, do: */
1600 if (!gTable->isEmpty())
1601 QTestResult::setCurrentGlobalTestData(gTable->testData(curGlobalDataIndex));
1603 if (curGlobalDataIndex == 0) {
1604 qsnprintf(member, 512, "%s_data()", slot);
1605 invokeMethod(QTest::currentTestObject, member);
1608 bool foundFunction = false;
1609 if (!QTestResult::skipCurrentTest()) {
1610 int curDataIndex = 0;
1611 const int dataCount = table.dataCount();
1613 // Data tag requested but none available?
1614 if (data && !dataCount) {
1615 // Let empty data tag through.
1619 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1620 fprintf(stderr, "Function has no testdata.\n");
1625 /* For each entry in the data table, do: */
1627 QTestResult::setSkipCurrentTest(false);
1628 if (!data || !qstrcmp(data, table.testData(curDataIndex)->dataTag())) {
1629 foundFunction = true;
1630 QTestDataSetter s(curDataIndex >= dataCount ? static_cast<QTestData *>(0)
1631 : table.testData(curDataIndex));
1633 qInvokeTestMethodDataEntry(slot);
1639 } while (curDataIndex < dataCount);
1642 if (data && !foundFunction) {
1643 fprintf(stderr, "Unknown testdata for function %s: '%s'\n", slotName, data);
1644 fprintf(stderr, "Available testdata:\n");
1645 for (int i = 0; i < table.dataCount(); ++i)
1646 fprintf(stderr, "%s\n", table.testData(i)->dataTag());
1650 QTestResult::setCurrentGlobalTestData(0);
1651 ++curGlobalDataIndex;
1652 } while (curGlobalDataIndex < globalDataCount);
1654 QTestResult::finishedCurrentTestFunction();
1655 QTestResult::setSkipCurrentTest(false);
1656 QTestResult::setCurrentTestData(0);
1662 void *fetchData(QTestData *data, const char *tagName, int typeId)
1664 QTEST_ASSERT(typeId);
1665 QTEST_ASSERT_X(data, "QTest::fetchData()", "Test data requested, but no testdata available.");
1666 QTEST_ASSERT(data->parent());
1668 int idx = data->parent()->indexOf(tagName);
1670 if (idx == -1 || idx >= data->dataCount()) {
1671 qFatal("QFETCH: Requested testdata '%s' not available, check your _data function.",
1675 if (typeId != data->parent()->elementTypeId(idx)) {
1676 qFatal("Requested type '%s' does not match available type '%s'.",
1677 QMetaType::typeName(typeId),
1678 QMetaType::typeName(data->parent()->elementTypeId(idx)));
1681 return data->data(idx);
1685 \fn char* QTest::toHexRepresentation(const char *ba, int length)
1687 Returns a pointer to a string that is the string \a ba represented
1688 as a space-separated sequence of hex characters. If the input is
1689 considered too long, it is truncated. A trucation is indicated in
1690 the returned string as an ellipsis at the end.
1692 \a length is the length of the string \a ba.
1694 char *toHexRepresentation(const char *ba, int length)
1699 /* We output at maximum about maxLen characters in order to avoid
1700 * running out of memory and flooding things when the byte array
1703 * maxLen can't be for example 200 because QTestLib is sprinkled with fixed
1706 const int maxLen = 50;
1707 const int len = qMin(maxLen, length);
1710 if (length > maxLen) {
1711 const int size = len * 3 + 4;
1712 result = new char[size];
1714 char *const forElipsis = result + size - 5;
1715 forElipsis[0] = ' ';
1716 forElipsis[1] = '.';
1717 forElipsis[2] = '.';
1718 forElipsis[3] = '.';
1719 result[size - 1] = '\0';
1722 const int size = len * 3;
1723 result = new char[size];
1724 result[size - 1] = '\0';
1727 const char toHex[] = "0123456789ABCDEF";
1732 const char at = ba[i];
1734 result[o] = toHex[(at >> 4) & 0x0F];
1736 result[o] = toHex[at & 0x0F];
1751 static void qInvokeTestMethods(QObject *testObject)
1753 const QMetaObject *metaObject = testObject->metaObject();
1754 QTEST_ASSERT(metaObject);
1755 QTestLog::startLogging();
1756 QTestResult::setCurrentTestFunction("initTestCase");
1757 QTestTable::globalTestTable();
1758 invokeMethod(testObject, "initTestCase_data()");
1760 if (!QTestResult::skipCurrentTest() && !QTest::currentTestFailed()) {
1761 invokeMethod(testObject, "initTestCase()");
1763 // finishedCurrentTestDataCleanup() resets QTestResult::currentTestFailed(), so use a local copy.
1764 const bool previousFailed = QTestResult::currentTestFailed();
1765 QTestResult::finishedCurrentTestData();
1766 QTestResult::finishedCurrentTestDataCleanup();
1767 QTestResult::finishedCurrentTestFunction();
1769 if (!QTestResult::skipCurrentTest() && !previousFailed) {
1771 if (QTest::testFuncs) {
1772 for (int i = 0; i != QTest::testFuncCount; i++) {
1773 if (!qInvokeTestMethod(metaObject->method(QTest::testFuncs[i].function()).signature(),
1774 QTest::testFuncs[i].data())) {
1778 testFuncCleaner.cleanup();
1780 int methodCount = metaObject->methodCount();
1781 QMetaMethod *testMethods = new QMetaMethod[methodCount];
1782 for (int i = 0; i != methodCount; i++)
1783 testMethods[i] = metaObject->method(i);
1784 for (int i = 0; i != methodCount; i++) {
1785 if (!isValidSlot(testMethods[i]))
1787 if (!qInvokeTestMethod(testMethods[i].signature()))
1790 delete[] testMethods;
1795 QTestResult::setSkipCurrentTest(false);
1796 QTestResult::setCurrentTestFunction("cleanupTestCase");
1797 invokeMethod(testObject, "cleanupTestCase()");
1798 QTestResult::finishedCurrentTestData();
1799 QTestResult::finishedCurrentTestDataCleanup();
1801 QTestResult::finishedCurrentTestFunction();
1802 QTestResult::setCurrentTestFunction(0);
1803 QTestTable::clearGlobalTestTable();
1805 QTestLog::stopLogging();
1808 #if defined(Q_OS_UNIX)
1809 class FatalSignalHandler
1812 FatalSignalHandler();
1813 ~FatalSignalHandler();
1816 static void signal(int);
1817 sigset_t handledSignals;
1820 void FatalSignalHandler::signal(int signum)
1822 qFatal("Received signal %d", signum);
1823 #if defined(Q_OS_INTEGRITY)
1825 struct sigaction act;
1826 memset(&act, 0, sizeof(struct sigaction));
1827 act.sa_handler = SIG_DFL;
1828 sigaction(signum, &act, NULL);
1833 FatalSignalHandler::FatalSignalHandler()
1835 sigemptyset(&handledSignals);
1837 const int fatalSignals[] = {
1838 SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGFPE, SIGSEGV, SIGPIPE, SIGTERM, 0 };
1840 struct sigaction act;
1841 memset(&act, 0, sizeof(act));
1842 act.sa_handler = FatalSignalHandler::signal;
1844 // Remove the handler after it is invoked.
1845 #if !defined(Q_OS_INTEGRITY)
1846 act.sa_flags = SA_RESETHAND;
1848 // Block all fatal signals in our signal handler so we don't try to close
1849 // the testlog twice.
1850 sigemptyset(&act.sa_mask);
1851 for (int i = 0; fatalSignals[i]; ++i)
1852 sigaddset(&act.sa_mask, fatalSignals[i]);
1854 struct sigaction oldact;
1856 for (int i = 0; fatalSignals[i]; ++i) {
1857 sigaction(fatalSignals[i], &act, &oldact);
1859 // Don't overwrite any non-default handlers
1860 // however, we need to replace the default QWS handlers
1863 oldact.sa_flags & SA_SIGINFO ||
1865 oldact.sa_handler != SIG_DFL) {
1866 sigaction(fatalSignals[i], &oldact, 0);
1870 sigaddset(&handledSignals, fatalSignals[i]);
1876 FatalSignalHandler::~FatalSignalHandler()
1878 // Unregister any of our remaining signal handlers
1879 struct sigaction act;
1880 memset(&act, 0, sizeof(act));
1881 act.sa_handler = SIG_DFL;
1883 struct sigaction oldact;
1885 for (int i = 1; i < 32; ++i) {
1886 if (!sigismember(&handledSignals, i))
1888 sigaction(i, &act, &oldact);
1890 // If someone overwrote it in the mean time, put it back
1891 if (oldact.sa_handler != FatalSignalHandler::signal)
1892 sigaction(i, &oldact, 0);
1902 Executes tests declared in \a testObject. In addition, the private slots
1903 \c{initTestCase()}, \c{cleanupTestCase()}, \c{init()} and \c{cleanup()}
1904 are executed if they exist. See \l{Creating a Test} for more details.
1906 Optionally, the command line arguments \a argc and \a argv can be provided.
1907 For a list of recognized arguments, read \l {QTestLib Command Line Arguments}.
1909 The following example will run all tests in \c MyTestObject:
1911 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 18
1913 This function returns 0 if no tests failed, or a value other than 0 if one
1914 or more tests failed or in case of unhandled exceptions. (Skipped tests do
1915 not influence the return value.)
1917 For stand-alone test applications, the convenience macro \l QTEST_MAIN() can
1918 be used to declare a main() function that parses the command line arguments
1919 and executes the tests, avoiding the need to call this function explicitly.
1921 The return value from this function is also the exit code of the test
1922 application when the \l QTEST_MAIN() macro is used.
1924 For stand-alone test applications, this function should not be called more
1925 than once, as command-line options for logging test output to files and
1926 executing individual test functions will not behave correctly.
1928 Note: This function is not reentrant, only one test can run at a time. A
1929 test that was executed with qExec() can't run another test via qExec() and
1930 threads are not allowed to call qExec() simultaneously.
1932 If you have programatically created the arguments, as opposed to getting them
1933 from the arguments in \c main(), it is likely of interest to use
1934 QTest::qExec(QObject *, const QStringList &) since it is Unicode safe.
1939 int QTest::qExec(QObject *testObject, int argc, char **argv)
1941 QBenchmarkGlobalData benchmarkData;
1942 QBenchmarkGlobalData::current = &benchmarkData;
1944 #ifdef QTESTLIB_USE_VALGRIND
1945 int callgrindChildExitCode = 0;
1949 bool macNeedsActivate = qApp && (qstrcmp(qApp->metaObject()->className(), "QApplication") == 0);
1950 IOPMAssertionID powerID;
1952 #ifndef QT_NO_EXCEPTIONS
1956 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
1957 # if !defined(Q_CC_MINGW) || (defined(Q_CC_MINGW) && defined(__MINGW64_VERSION_MAJOR))
1958 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
1960 SetErrorMode(SetErrorMode(0) | SEM_NOGPFAULTERRORBOX);
1964 // Starting with Qt 4.4, applications launched from the command line
1965 // no longer get focus automatically. Since some tests might depend
1966 // on this, call SetFrontProcess here to get the pre 4.4 behavior.
1967 if (macNeedsActivate) {
1968 ProcessSerialNumber psn = { 0, kCurrentProcess };
1969 SetFrontProcess(&psn);
1970 IOReturn ok = IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &powerID);
1971 if (ok != kIOReturnSuccess)
1972 macNeedsActivate = false; // no need to release the assertion on exit.
1976 QTestResult::reset();
1978 QTEST_ASSERT(testObject);
1979 QTEST_ASSERT(!currentTestObject);
1980 currentTestObject = testObject;
1982 const QMetaObject *metaObject = testObject->metaObject();
1983 QTEST_ASSERT(metaObject);
1985 QTestResult::setCurrentTestObject(metaObject->className());
1986 QTestResult::setCurrentAppname(argv[0]);
1988 qtest_qParseArgs(argc, argv, false);
1990 bool installedTestCoverage = installCoverageTool(argv[0], metaObject->className());
1991 QTestLog::setInstalledTestCoverage(installedTestCoverage);
1993 #ifdef QTESTLIB_USE_VALGRIND
1994 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess) {
1995 const QStringList origAppArgs(QCoreApplication::arguments());
1996 if (!QBenchmarkValgrindUtils::rerunThroughCallgrind(origAppArgs, callgrindChildExitCode))
1999 QBenchmarkValgrindUtils::cleanup();
2004 #if defined(Q_OS_UNIX)
2005 QScopedPointer<FatalSignalHandler> handler;
2006 if (!noCrashHandler)
2007 handler.reset(new FatalSignalHandler);
2009 qInvokeTestMethods(testObject);
2012 #ifndef QT_NO_EXCEPTIONS
2014 QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__);
2015 if (QTestResult::currentTestFunction()) {
2016 QTestResult::finishedCurrentTestFunction();
2017 QTestResult::setCurrentTestFunction(0);
2020 QTestLog::stopLogging();
2022 if (macNeedsActivate) {
2023 IOPMAssertionRelease(powerID);
2026 currentTestObject = 0;
2028 // Rethrow exception to make debugging easier.
2034 currentTestObject = 0;
2036 QSignalDumper::endDump();
2039 if (macNeedsActivate) {
2040 IOPMAssertionRelease(powerID);
2044 #ifdef QTESTLIB_USE_VALGRIND
2045 if (QBenchmarkGlobalData::current->mode() == QBenchmarkGlobalData::CallgrindParentProcess)
2046 return callgrindChildExitCode;
2048 // make sure our exit code is never going above 127
2049 // since that could wrap and indicate 0 test fails
2050 return qMin(QTestLog::failCount(), 127);
2057 Behaves identically to qExec(QObject *, int, char**) but takes a
2058 QStringList of \a arguments instead of a \c char** list.
2060 int QTest::qExec(QObject *testObject, const QStringList &arguments)
2062 const int argc = arguments.count();
2063 QVarLengthArray<char *> argv(argc);
2065 QVector<QByteArray> args;
2068 for (int i = 0; i < argc; ++i)
2070 args.append(arguments.at(i).toLocal8Bit().constData());
2071 argv[i] = args.last().data();
2074 return qExec(testObject, argc, argv.data());
2079 void QTest::qFail(const char *statementStr, const char *file, int line)
2081 QTestResult::addFailure(statementStr, file, line);
2086 bool QTest::qVerify(bool statement, const char *statementStr, const char *description,
2087 const char *file, int line)
2089 return QTestResult::verify(statement, statementStr, description, file, line);
2092 /*! \fn void QTest::qSkip(const char *message, const char *file, int line)
2095 void QTest::qSkip(const char *message, const char *file, int line)
2097 QTestResult::addSkip(message, file, line);
2098 QTestResult::setSkipCurrentTest(true);
2101 /*! \fn bool QTest::qExpectFail(const char *dataIndex, const char *comment, TestFailMode mode, const char *file, int line)
2104 bool QTest::qExpectFail(const char *dataIndex, const char *comment,
2105 QTest::TestFailMode mode, const char *file, int line)
2107 return QTestResult::expectFail(dataIndex, qstrdup(comment), mode, file, line);
2112 void QTest::qWarn(const char *message, const char *file, int line)
2114 QTestLog::warn(message, file, line);
2118 Ignores messages created by qDebug() or qWarning(). If the \a message
2119 with the corresponding \a type is outputted, it will be removed from the
2120 test log. If the test finished and the \a message was not outputted,
2121 a test failure is appended to the test log.
2123 \bold {Note:} Invoking this function will only ignore one message.
2124 If the message you want to ignore is outputted twice, you have to
2125 call ignoreMessage() twice, too.
2128 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 19
2130 The example above tests that QDir::mkdir() outputs the right warning when invoked
2131 with an invalid file name.
2133 void QTest::ignoreMessage(QtMsgType type, const char *message)
2135 QTestLog::ignoreMessage(type, message);
2142 static inline bool isWindowsBuildDirectory(const QString &dirName)
2144 return dirName.compare(QStringLiteral("Debug"), Qt::CaseInsensitive) == 0
2145 || dirName.compare(QStringLiteral("Release"), Qt::CaseInsensitive) == 0;
2149 QString QTest::qFindTestData(const QString& base, const char *file, int line, const char *builddir)
2153 // Testdata priorities:
2155 // 1. relative to test binary.
2157 QDir binDirectory(QCoreApplication::applicationDirPath());
2158 if (binDirectory.exists(base)) {
2159 found = binDirectory.absoluteFilePath(base);
2162 // Windows: The executable is typically located in one of the
2163 // 'Release' or 'Debug' directories.
2164 else if (isWindowsBuildDirectory(binDirectory.dirName())
2165 && binDirectory.cdUp() && binDirectory.exists(base)) {
2166 found = binDirectory.absoluteFilePath(base);
2169 else if (QTestLog::verboseLevel() >= 2) {
2170 const QString candidate = QDir::toNativeSeparators(QCoreApplication::applicationDirPath() + QLatin1Char('/') + base);
2171 QTestLog::info(qPrintable(
2172 QString::fromLatin1("testdata %1 not found relative to test binary [%2]; "
2173 "checking next location").arg(base, candidate)),
2178 // 2. installed path.
2179 if (found.isEmpty()) {
2180 const char *testObjectName = QTestResult::currentTestObjectName();
2181 if (testObjectName) {
2182 QString testsPath = QLibraryInfo::location(QLibraryInfo::TestsPath);
2183 QString candidate = QString::fromLatin1("%1/%2/%3")
2184 .arg(testsPath, QFile::decodeName(testObjectName).toLower(), base);
2185 if (QFileInfo(candidate).exists()) {
2188 else if (QTestLog::verboseLevel() >= 2) {
2189 QTestLog::info(qPrintable(
2190 QString::fromLatin1("testdata %1 not found in tests install path [%2]; "
2191 "checking next location")
2192 .arg(base, QDir::toNativeSeparators(candidate))),
2198 // 3. relative to test source.
2199 if (found.isEmpty()) {
2200 // srcdir is the directory containing the calling source file.
2201 QFileInfo srcdir = QFileInfo(QFile::decodeName(file)).path();
2203 // If the srcdir is relative, that means it is relative to the current working
2204 // directory of the compiler at compile time, which should be passed in as `builddir'.
2205 if (!srcdir.isAbsolute() && builddir) {
2206 srcdir.setFile(QFile::decodeName(builddir) + QLatin1String("/") + srcdir.filePath());
2209 QString candidate = QString::fromLatin1("%1/%2").arg(srcdir.canonicalFilePath(), base);
2210 if (QFileInfo(candidate).exists()) {
2213 else if (QTestLog::verboseLevel() >= 2) {
2214 QTestLog::info(qPrintable(
2215 QString::fromLatin1("testdata %1 not found relative to source path [%2]")
2216 .arg(base, QDir::toNativeSeparators(candidate))),
2221 if (found.isEmpty()) {
2222 QTest::qWarn(qPrintable(
2223 QString::fromLatin1("testdata %1 could not be located!").arg(base)),
2226 else if (QTestLog::verboseLevel() >= 1) {
2227 QTestLog::info(qPrintable(
2228 QString::fromLatin1("testdata %1 was located at %2").arg(base, QDir::toNativeSeparators(found))),
2237 QString QTest::qFindTestData(const char *base, const char *file, int line, const char *builddir)
2239 return qFindTestData(QFile::decodeName(base), file, line, builddir);
2244 void *QTest::qData(const char *tagName, int typeId)
2246 return fetchData(QTestResult::currentTestData(), tagName, typeId);
2251 void *QTest::qGlobalData(const char *tagName, int typeId)
2253 return fetchData(QTestResult::currentGlobalTestData(), tagName, typeId);
2258 void *QTest::qElementData(const char *tagName, int metaTypeId)
2260 QTEST_ASSERT(tagName);
2261 QTestData *data = QTestResult::currentTestData();
2263 QTEST_ASSERT(data->parent());
2265 int idx = data->parent()->indexOf(tagName);
2266 QTEST_ASSERT(idx != -1);
2267 QTEST_ASSERT(data->parent()->elementTypeId(idx) == metaTypeId);
2269 return data->data(data->parent()->indexOf(tagName));
2274 void QTest::addColumnInternal(int id, const char *name)
2276 QTestTable *tbl = QTestTable::currentTestTable();
2277 QTEST_ASSERT_X(tbl, "QTest::addColumn()", "Cannot add testdata outside of a _data slot.");
2279 tbl->addColumn(id, name);
2283 Appends a new row to the current test data. \a dataTag is the name of
2284 the testdata that will appear in the test output. Returns a QTestData reference
2285 that can be used to stream in data.
2288 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 20
2290 \bold {Note:} This macro can only be used in a test's data function
2291 that is invoked by the test framework.
2293 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2294 a more extensive example.
2296 \sa addColumn(), QFETCH()
2298 QTestData &QTest::newRow(const char *dataTag)
2300 QTEST_ASSERT_X(dataTag, "QTest::newRow()", "Data tag can not be null");
2301 QTestTable *tbl = QTestTable::currentTestTable();
2302 QTEST_ASSERT_X(tbl, "QTest::newRow()", "Cannot add testdata outside of a _data slot.");
2303 QTEST_ASSERT_X(tbl->elementCount(), "QTest::newRow()", "Must add columns before attempting to add rows.");
2305 return *tbl->newData(dataTag);
2308 /*! \fn void QTest::addColumn(const char *name, T *dummy = 0)
2310 Adds a column with type \c{T} to the current test data.
2311 \a name is the name of the column. \a dummy is a workaround
2312 for buggy compilers and can be ignored.
2314 To populate the column with values, newRow() can be used. Use
2315 \l QFETCH() to fetch the data in the actual test.
2318 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 21
2320 To add custom types to the testdata, the type must be registered with
2321 QMetaType via \l Q_DECLARE_METATYPE().
2323 \bold {Note:} This macro can only be used in a test's data function
2324 that is invoked by the test framework.
2326 See \l {Chapter 2: Data Driven Testing}{Data Driven Testing} for
2327 a more extensive example.
2329 \sa QTest::newRow(), QFETCH(), QMetaType
2333 Returns the name of the test function that is currently executed.
2337 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 22
2339 const char *QTest::currentTestFunction()
2341 return QTestResult::currentTestFunction();
2345 Returns the name of the current test data. If the test doesn't
2346 have any assigned testdata, the function returns 0.
2348 const char *QTest::currentDataTag()
2350 return QTestResult::currentDataTag();
2354 Returns true if the current test function failed, otherwise false.
2356 bool QTest::currentTestFailed()
2358 return QTestResult::currentTestFailed();
2362 Sleeps for \a ms milliseconds, blocking execution of the
2363 test. qSleep() will not do any event processing and leave your test
2364 unresponsive. Network communication might time out while
2365 sleeping. Use \l qWait() to do non-blocking sleeping.
2367 \a ms must be greater than 0.
2369 \bold {Note:} The qSleep() function calls either \c nanosleep() on
2370 unix or \c Sleep() on windows, so the accuracy of time spent in
2371 qSleep() depends on the operating system.
2374 \snippet doc/src/snippets/code/src_qtestlib_qtestcase.cpp 23
2378 void QTest::qSleep(int ms)
2380 QTEST_ASSERT(ms > 0);
2385 struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
2386 nanosleep(&ts, NULL);
2392 QObject *QTest::testObject()
2394 return currentTestObject;
2399 bool QTest::compare_helper(bool success, const char *msg, const char *file, int line)
2401 return QTestResult::compare(success, msg, file, line);
2406 bool QTest::compare_helper(bool success, const char *msg, char *val1, char *val2,
2407 const char *actual, const char *expected, const char *file, int line)
2409 return QTestResult::compare(success, msg, val1, val2, actual, expected, file, line);
2412 /*! \fn bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected, const char *file, int line)
2416 Q_TESTLIB_EXPORT bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
2417 const char *file, int line)
2419 return qFuzzyCompare(t1, t2)
2420 ? compare_helper(true, "COMPARE()", file, line)
2421 : compare_helper(false, "Compared floats are not the same (fuzzy compare)",
2422 toString(t1), toString(t2), actual, expected, file, line);
2425 /*! \fn bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected, const char *file, int line)
2429 Q_TESTLIB_EXPORT bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
2430 const char *file, int line)
2432 return qFuzzyCompare(t1, t2)
2433 ? compare_helper(true, "COMPARE()", file, line)
2434 : compare_helper(false, "Compared doubles are not the same (fuzzy compare)",
2435 toString(t1), toString(t2), actual, expected, file, line);
2438 #define TO_STRING_IMPL(TYPE, FORMAT) \
2439 template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE >(const TYPE &t) \
2441 char *msg = new char[128]; \
2442 qsnprintf(msg, 128, #FORMAT, t); \
2446 TO_STRING_IMPL(short, %hd)
2447 TO_STRING_IMPL(ushort, %hu)
2448 TO_STRING_IMPL(int, %d)
2449 TO_STRING_IMPL(uint, %u)
2450 TO_STRING_IMPL(long, %ld)
2451 TO_STRING_IMPL(ulong, %lu)
2452 #if defined(Q_OS_WIN)
2453 TO_STRING_IMPL(qint64, %I64d)
2454 TO_STRING_IMPL(quint64, %I64u)
2456 TO_STRING_IMPL(qint64, %lld)
2457 TO_STRING_IMPL(quint64, %llu)
2459 TO_STRING_IMPL(bool, %d)
2460 TO_STRING_IMPL(char, %c)
2461 TO_STRING_IMPL(float, %g)
2462 TO_STRING_IMPL(double, %lg)
2466 char *QTest::toString(const char *str)
2470 char *msg = new char[strlen(str) + 1];
2471 return qstrcpy(msg, str);
2476 char *QTest::toString(const void *p)
2478 char *msg = new char[128];
2479 qsnprintf(msg, 128, "%p", p);
2485 bool QTest::compare_string_helper(const char *t1, const char *t2, const char *actual,
2486 const char *expected, const char *file, int line)
2488 return (qstrcmp(t1, t2) == 0)
2489 ? compare_helper(true, "COMPARE()", file, line)
2490 : compare_helper(false, "Compared strings are not the same",
2491 toString(t1), toString(t2), actual, expected, file, line);
2494 /*! \fn bool QTest::compare_ptr_helper(const void *t1, const void *t2, const char *actual, const char *expected, const char *file, int line);
2498 /*! \fn bool QTest::qCompare(T1 const &, T2 const &, const char *, const char *, const char *, int);
2503 /*! \fn void QTest::mouseEvent(MouseAction action, QWidget *widget, Qt::MouseButton button, Qt::KeyboardModifiers stateKey, QPoint pos, int delay=-1)
2507 /*! \fn bool QTest::qCompare(QIcon const &t1, QIcon const &t2, const char *actual, const char *expected, const char *file, int line)
2511 /*! \fn bool QTest::qCompare(QPixmap const &t1, QPixmap const &t2, const char *actual, const char *expected, const char *file, int line)
2515 /*! \fn bool QTest::qCompare(T const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2519 /*! \fn bool QTest::qCompare(const T *t1, const T *t2, const char *actual, const char *expected, const char *file, int line)
2523 /*! \fn bool QTest::qCompare(T *t1, T *t2, const char *actual, const char *expected, const char *file, int line)
2527 /*! \fn bool QTest::qCompare(const T1 *t1, const T2 *t2, const char *actual, const char *expected, const char *file, int line)
2531 /*! \fn bool QTest::qCompare(T1 *t1, T2 *t2, const char *actual, const char *expected, const char *file, int line)
2535 /*! \fn bool QTest::qCompare(const char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2539 /*! \fn bool QTest::qCompare(char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2543 /*! \fn bool QTest::qCompare(char *t1, const char *t2, const char *actual, const char *expected, const char *file, int line)
2547 /*! \fn bool QTest::qCompare(const char *t1, char *t2, const char *actual, const char *expected, const char *file, int line)
2551 /*! \fn bool QTest::qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
2555 /*! \fn bool QTest::qCompare(QLatin1String const &t1, QString const &t2, const char *actual, const char *expected, const char *file, int line)
2559 /*! \fn bool QTest::qCompare(QStringList const &t1, QStringList const &t2, const char *actual, const char *expected, const char *file, int line)
2563 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, T const &t2, const char *actual, const char *expected, const char *file, int line)
2567 /*! \fn bool QTest::qCompare(QFlags<T> const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2571 /*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line)
2575 /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line)
2579 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, QString text, Qt::KeyboardModifiers modifier, int delay=-1)
2583 /*! \fn void QTest::sendKeyEvent(KeyAction action, QWidget *widget, Qt::Key code, char ascii, Qt::KeyboardModifiers modifier, int delay=-1)
2587 /*! \fn void QTest::simulateEvent(QWidget *widget, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)