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 finished or failed
# signals is emitted or 10 seconds has elapsed
assert blocker.signal_triggered, "process timed-out"
assert_application_results(app)
raising parameter¶
New in version 1.4.
You can pass raising=True
to raise 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=True) as blocker:
app.worker.start()
# if timeout is reached, qtbot.SignalTimeoutError will be raised at this point
assert_application_results(app)
Note
The default value for raising
is planned to change to True
starting in
pytest-qt version 1.12
. Users wishing to preserve
the current behavior (raising
is False
by default) should make
use of the new qt_wait_signal_raising ini option.
qt_wait_signal_raising ini option¶
New in version 1.11.
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 = true
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.waitSignal([w.finished for w in workers], raising=True):
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()