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