waitSignal: Waiting for threads, processes, etc.¶
New in version 1.2.
If your program has long running computations running in other threads or
processes, you can use qtbot.waitSignal
to block a test until a signal is emitted (such as QThread.finished
) or a
timeout is reached. This makes it easy to write tests that wait until a
computation running in another thread or process is completed before
ensuring the results are correct:
def test_long_computation(qtbot):
app = Application()
# Watch for the app.worker.finished signal, then start the worker.
with qtbot.waitSignal(app.worker.finished, timeout=10000) as blocker:
blocker.connect(app.worker.failed) # Can add other signals to blocker
app.worker.start()
# Test will block at this point until either the "finished" or the
# "failed" signal is emitted. If 10 seconds passed without a signal,
# SignalTimeoutError will be raised.
assert_application_results(app)
raising parameter¶
New in version 1.4.
Changed in version 2.0.
You can pass raising=False
to avoid raising a
qtbot.SignalTimeoutError
if the timeout is
reached before the signal is triggered:
def test_long_computation(qtbot):
...
with qtbot.waitSignal(app.worker.finished, raising=False) as blocker:
app.worker.start()
assert_application_results(app)
# qtbot.SignalTimeoutError is not raised, but you can still manually
# check whether the signal was triggered:
assert blocker.signal_triggered, "process timed-out"
qt_wait_signal_raising ini option¶
New in version 1.11.
Changed in version 2.0.
The qt_wait_signal_raising
ini option can be used to override the default
value of the raising
parameter of the qtbot.waitSignal
and
qtbot.waitSignals
functions when omitted:
[pytest]
qt_wait_signal_raising = false
Calls which explicitly pass the raising
parameter are not affected.
Getting arguments of the emitted signal¶
New in version 1.10.
The arguments emitted with the signal are available as the args
attribute
of the blocker:
def test_signal(qtbot):
...
with qtbot.waitSignal(app.got_cmd) as blocker:
app.listen()
assert blocker.args == ['test']
Signals without arguments will set args
to an empty list. If the time out
is reached instead, args
will be None
.
waitSignals¶
New in version 1.4.
If you have to wait until all signals in a list are triggered, use
qtbot.waitSignals
, which receives
a list of signals instead of a single signal. As with
qtbot.waitSignal
, it also supports
the raising
parameter:
def test_workers(qtbot):
workers = spawn_workers()
with qtbot.waitSignals([w.finished for w in workers]):
for w in workers:
w.start()
# this will be reached after all workers emit their "finished"
# signal or a qtbot.SignalTimeoutError will be raised
assert_application_results(app)
Making sure a given signal is not emitted¶
New in version 1.11.
If you want to ensure a signal is not emitted in a given block of code, use
the qtbot.assertNotEmitted
context manager:
def test_no_error(qtbot):
...
with qtbot.assertNotEmitted(app.worker.error):
app.worker.start()