Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qtestsupport_core.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <thread>
8
9using namespace std::chrono_literals;
10
11QT_BEGIN_NAMESPACE
12
13// ### Qt 7: reduce the default: QTBUG-138160
14Q_CONSTINIT std::atomic<std::chrono::milliseconds> QTest::defaultTryTimeout{5s};
15
16/*!
17 \variable QTest::defaultTryTimeout
18 \since 6.11
19
20 This global variable stores the default timeout used by the \c {QTRY_*}
21 functions and \l qWait.
22
23 The most typical use case for this variable is to modify the timeout
24 for an entire test:
25
26 \snippet code/src_qtestlib_qtestcase.cpp set defaultTryTimeout
27
28 However, you can also set it for a specific scope, using
29 \l QAtomicScopedValueRollback:
30
31 \snippet code/src_qtestlib_qtestcase.cpp rollback defaultTryTimeout
32
33 To access the value, call \c load():
34
35 \snippet code/src_qtestlib_qtestcase.cpp get defaultTryTimeout
36*/
37
38/*!
39 \overload
40
41 Sleeps for \a ms milliseconds, blocking execution of the test.
42
43 Equivalent to calling:
44 \code
45 QTest::qSleep(std::chrono::milliseconds{ms});
46 \endcode
47*/
48void QTest::qSleep(int ms)
49{
50 QTest::qSleep(std::chrono::milliseconds{ms});
51}
52
53/*!
54 \since 6.7
55
56 Sleeps for \a msecs, blocking execution of the test.
57
58 This method will not do any event processing and will leave your test
59 unresponsive. Network communication might time out while sleeping.
60 Use \l {QTest::qWait()} to do non-blocking sleeping.
61
62 \a msecs must be greater than 0ms.
63
64 \note Starting from Qt 6.7, this function is implemented using
65 \c {std::this_thread::sleep_for}, so the accuracy of time spent depends
66 on the Standard Library implementation. Before Qt 6.7 this function called
67 either \c nanosleep() on Unix or \c Sleep() on Windows, so the accuracy of
68 time spent in this function depended on the operating system.
69
70 Example:
71 \snippet code/src_qtestlib_qtestcase.cpp 23
72
73 \sa {QTest::qWait()}
74*/
75void QTest::qSleep(std::chrono::milliseconds msecs)
76{
77 Q_ASSERT(msecs > 0ms);
78 std::this_thread::sleep_for(msecs);
79}
80
81/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout)
82
83 \since 5.10
84 \overload
85
86 Waits for \a timeout milliseconds or until the \a predicate returns true.
87
88 This is equivalent to calling:
89 \code
90 qWaitFor(predicate, QDeadlineTimer(timeout));
91 \endcode
92*/
93
94/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, QDeadlineTimer deadline)
95 \since 6.7
96
97 Waits until \a deadline has expired, or until \a predicate returns true, whichever
98 happens first.
99
100 Returns \c true if \a predicate returned true at any point, otherwise returns \c false.
101
102 Example:
103
104 \snippet code/src_corelib_kernel_qtestsupport_core.cpp 2
105
106 The code above will wait for the object to become ready, for a
107 maximum of three seconds.
108*/
109
110/*!
111 \overload
112
113 Waits for \a msecs. Equivalent to calling:
114 \code
115 QTest::qWait(std::chrono::milliseconds{msecs});
116 \endcode
117*/
118Q_CORE_EXPORT void QTest::qWait(int msecs)
119{
120 qWait(std::chrono::milliseconds{msecs});
121}
122
123/*!
124 \since 6.7
125
126 Waits for \a msecs. While waiting, events will be processed and
127 your test will stay responsive to user interface events or network communication.
128
129 Example:
130
131 \snippet code/src_corelib_kernel_qtestsupport_core.cpp 1
132
133 The code above will wait until the network server is responding for a
134 maximum of about 12.5 seconds.
135
136 The \l{QTRY_COMPARE()}{QTRY_*} macros are usually a better choice than
137 qWait(). qWait() always pauses for the full timeout, which can leave the
138 test idle and slow down execution.
139
140 The \c {QTRY_*} macros poll the condition until it succeeds or the timeout
141 expires. Your test therefore continues as soon as possible and stays more
142 reliable. If the condition still fails, the macros double the timeout once
143 and report the new value so that you can adjust it.
144
145 For example, rewrite the code above as:
146
147 \code
148 QTRY_VERIFY_WITH_TIMEOUT(!myNetworkServerNotResponding(), 12.5s);
149 \endcode
150
151 \sa QTest::qSleep(), QSignalSpy::wait(), QTRY_VERIFY_WITH_TIMEOUT()
152*/
153Q_CORE_EXPORT void QTest::qWait(std::chrono::milliseconds msecs)
154{
155 // Ideally this method would be implemented in terms of qWaitFor(), with a
156 // predicate that always returns false, but qWaitFor() uses the 1-arg overload
157 // of processEvents(), which doesn't handle events posted in this round of event
158 // processing, which, together with the 10ms qSleep() after every processEvents(),
159 // lead to a 10x slow-down in some webengine tests.
160
161 Q_ASSERT(QCoreApplication::instance());
162
163 using namespace std::chrono;
164
165 QDeadlineTimer deadline(msecs, Qt::PreciseTimer);
166
167 do {
168 QCoreApplication::processEvents(QEventLoop::AllEvents, deadline);
169 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
170
171 // If dealine is Forever, processEvents() has already looped forever
172 if (deadline.isForever())
173 break;
174
175 msecs = ceil<milliseconds>(deadline.remainingTimeAsDuration());
176 if (msecs == 0ms)
177 break;
178
179 QTest::qSleep(std::min(10ms, msecs));
180 } while (!deadline.hasExpired());
181}
182
183QT_END_NAMESPACE
Q_CORE_EXPORT void qWait(std::chrono::milliseconds msecs)
Q_CORE_EXPORT void qSleep(int ms)
\variable QTest::defaultTryTimeout
Q_CORE_EXPORT void qSleep(std::chrono::milliseconds msecs)
Q_CORE_EXPORT void qWait(int ms)
This is an overloaded member function, provided for convenience. It differs from the above function o...