Reference
QtBot
- class pytestqt.qtbot.QtBot(request)[source]
Instances of this class are responsible for sending events to Qt objects (usually widgets), simulating user input.
Important
Instances of this class should be accessed only by using a
qtbot
fixture, never instantiated directly.Widgets
- addWidget(widget, *, before_close_func=None)[source]
Adds a widget to be tracked by this bot. This is not required, but will ensure that the widget gets closed by the end of the test, so it is highly recommended.
- Parameters:
widget (QWidget) – Widget to keep track of.
before_close_func – A function that receives the widget as single parameter, which is called just before the
.close()
method gets called.
Note
This method is also available as
add_widget
(pep-8 alias)
- captureExceptions()[source]
Added in version 2.1.
Context manager that captures Qt virtual method exceptions that happen in block inside context.
with qtbot.capture_exceptions() as exceptions: qtbot.mouseClick( button, QtCore.MouseButton.LeftButton # for PyQt6 ) # ... or QtCore.LeftButton in PyQt5 # exception is a list of sys.exc_info tuples assert len(exceptions) == 1
Note
This method is also available as
capture_exceptions
(pep-8 alias)
- waitActive(widget, *, timeout=5000)[source]
Context manager that waits for
timeout
milliseconds or until the window is active. If window is not exposed withintimeout
milliseconds, raiseqtbot.TimeoutError
This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some time after being asked to show itself on the screen.
with qtbot.waitActive(widget, timeout=500): show_action()
- Parameters:
widget (QWidget) – Widget to wait for.
timeout (int|None) – How many milliseconds to wait for.
Note
This method is also available as
wait_active
(pep-8 alias)
- waitExposed(widget, *, timeout=5000)[source]
Context manager that waits for
timeout
milliseconds or until the window is exposed. If the window is not exposed withintimeout
milliseconds, raiseqtbot.TimeoutError
This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some time after being asked to show itself on the screen.
with qtbot.waitExposed(splash, timeout=500): startup()
- Parameters:
widget (QWidget) – Widget to wait for.
timeout (int|None) – How many milliseconds to wait for.
Note
This method is also available as
wait_exposed
(pep-8 alias)
- waitForWindowShown(widget)[source]
Waits until the window is shown in the screen. This is mainly useful for asynchronous systems like X11, where a window will be mapped to screen some time after being asked to show itself on the screen.
Warning
This method does not raise
qtbot.TimeoutError
if the window wasn’t shown.Deprecated since version 4.0: Use the
qtbot.waitExposed
context manager instead.- Parameters:
widget (QWidget) – Widget to wait on.
- Returns:
True
if the window was shown,False
if.show()
was never called or a timeout occurred.
Note
This method is also available as
wait_for_window_shown
(pep-8 alias)
- stop()[source]
Stops the current test flow, letting the user interact with any visible widget.
This is mainly useful so that you can verify the current state of the program while writing tests.
Closing the windows should resume the test run, with
qtbot
attempting to restore visibility of the widgets as they were before this call.
- screenshot(widget, suffix='', region=None)[source]
Added in version 4.1.
Take a screenshot of the given widget and save it.
The file is saved in a test-specific directory using pytest’s
tmp_path
fixture. The filename is ensured to be unique using a counter, and contains theobjectName()
of the widget if set, as well as its class name. A customsuffix
can be given to add to the generated name.Raises
qtbot.ScreenshotError
if taking the screenshot or saving the file failed.- Parameters:
widget (QWidget) – The widget to take a screenshot of.
suffix (str) – An optional suffix to add to the filename.
region (QRect) – The region of the widget to screeshot. By default, the entire widget is contained.
- Returns:
A
pathlib.Path
object with the taken screenshot.
- wait(ms)[source]
Added in version 1.9.
Waits for
ms
milliseconds.While waiting, events will be processed and your test will stay responsive to user interface events or network communication.
Signals and Events
- waitSignal(signal, *, timeout=5000, raising=None, check_params_cb=None)[source]
Added in version 1.2.
Stops current test until a signal is triggered.
Used to stop the control flow of a test until a signal is emitted, or a number of milliseconds, specified by
timeout
, has elapsed.Best used as a context manager:
with qtbot.waitSignal(signal, timeout=1000): long_function_that_calls_signal()
Also, you can use the
SignalBlocker
directly if the context manager form is not convenient:blocker = qtbot.waitSignal(signal, timeout=1000) blocker.connect(another_signal) long_function_that_calls_signal() blocker.wait()
Any additional signal, when triggered, will make
wait()
return.Added in version 1.4: The raising parameter.
Added in version 2.0: The check_params_cb parameter.
- Parameters:
signal (Signal) – A signal to wait for, or a tuple
(signal, signal_name_as_str)
to improve the error message that is part ofqtbot.TimeoutError
.timeout (int) – How many milliseconds to wait before resuming control flow.
raising (bool) – If
qtbot.TimeoutError
should be raised if a timeout occurred. This defaults toTrue
unlessqt_default_raising = false
is set in the config.check_params_cb (Callable) – Optional
callable
that compares the provided signal parameters to some expected parameters. It has to match the signature ofsignal
(just like a slot function would) and returnTrue
if parameters match,False
otherwise.
- Returns:
SignalBlocker
object. CallSignalBlocker.wait()
to wait.
Note
This method is also available as
wait_signal
(pep-8 alias)
- waitSignals(signals, *, timeout=5000, raising=None, check_params_cbs=None, order='none')[source]
Added in version 1.4.
Stops current test until all given signals are triggered.
Used to stop the control flow of a test until all (and only all) signals are emitted or the number of milliseconds specified by
timeout
has elapsed.Best used as a context manager:
with qtbot.waitSignals([signal1, signal2], timeout=1000): long_function_that_calls_signals()
Also, you can use the
MultiSignalBlocker
directly if the context manager form is not convenient:blocker = qtbot.waitSignals(signals, timeout=1000) long_function_that_calls_signal() blocker.wait()
- Parameters:
signals (list) – A list of
Signal
objects to wait for. Alternatively: a list of (Signal, str
) tuples of the form(signal, signal_name_as_str)
to improve the error message that is part ofqtbot.TimeoutError
.timeout (int) – How many milliseconds to wait before resuming control flow.
raising (bool) – If
qtbot.TimeoutError
should be raised if a timeout occurred. This defaults toTrue
unlessqt_default_raising = false
is set in the config.check_params_cbs (list) – optional list of callables that compare the provided signal parameters to some expected parameters. Each callable has to match the signature of the corresponding signal in
signals
(just like a slot function would) and returnTrue
if parameters match,False
otherwise. Instead of a specific callable,None
can be provided, to disable parameter checking for the corresponding signal. If the number of callbacks doesn’t match the number of signalsValueError
will be raised.order (str) –
Determines the order in which to expect signals:
"none"
: no order is enforced"strict"
: signals have to be emitted strictly in the provided order (e.g. fails when expecting signals [a, b] and [a, a, b] is emitted)"simple"
: like “strict”, but signals may be emitted in-between the provided ones, e.g. expectedsignals == [a, b, c]
and actually emittedsignals = [a, a, b, a, c]
works (would fail with"strict"
).
- Returns:
MultiSignalBlocker
object. CallMultiSignalBlocker.wait()
to wait.
Note
This method is also available as
wait_signals
(pep-8 alias)
- assertNotEmitted(signal, *, wait=0)[source]
Added in version 1.11.
Make sure the given
signal
doesn’t get emitted.- Parameters:
wait (int) – How many milliseconds to wait to make sure the signal isn’t emitted asynchronously. By default, this method returns immediately and only catches signals emitted inside the
with
-block.
This is intended to be used as a context manager.
Note
This method is also available as
assert_not_emitted
(pep-8 alias)
- waitUntil(callback, *, timeout=5000)[source]
Added in version 2.0.
Wait in a busy loop, calling the given callback periodically until timeout is reached.
callback()
should raiseAssertionError
to indicate that the desired condition has not yet been reached, or just returnNone
when it does. Useful toassert
until some condition is satisfied:def view_updated(): assert view_model.count() > 10 qtbot.waitUntil(view_updated)
Another possibility is for
callback()
to returnTrue
when the desired condition is met,False
otherwise. Useful specially withlambda
for terser code, but keep in mind that the error message in those cases is usually not very useful because it is not using anassert
expression.qtbot.waitUntil(lambda: view_model.count() > 10)
Note that this usage only accepts returning actual
True
andFalse
values, so returning an empty list to express “falseness” raises aValueError
.- Parameters:
callback – callable that will be called periodically.
timeout – timeout value in ms.
- Raises:
ValueError – if the return value from the callback is anything other than
None
,True
orFalse
.
Note
This method is also available as
wait_until
(pep-8 alias)
Raw QTest API
Methods below provide very low level functions, as sending a single mouse click or a key event. Those methods are just forwarded directly to the QTest API. Consult the documentation for more information.
Note
These methods should be rarely be used, in general prefer to interact with widgets using their own methods such as
QComboBox.setCurrentText
,QLineEdit.setText
, etc. Doing so will have the same effect as users interacting with the widget, but are more reliable.See this note in the tutorial for more information.
—
Below are methods used to simulate sending key events to widgets:
- static keyClicks(widget, key_sequence[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]])[source]
- static keyEvent(action, widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]])[source]
- static keyRelease(widget, key[, modifier=Qt.KeyboardModifier.NoModifier[, delay=-1]])[source]
Sends one or more keyboard events to a widget.
- Parameters:
widget (QWidget) – the widget that will receive the event
key (str|int) – key to send, it can be either a Qt.Key.Key_* constant or a single character string.
- Parameters:
modifier (Qt.KeyboardModifier) –
flags OR’ed together representing other modifier keys also pressed. Possible flags are:
Qt.KeyboardModifier.NoModifier
: No modifier key is pressed.Qt.KeyboardModifier.ShiftModifier
: A Shift key on the keyboard is pressed.Qt.KeyboardModifier.ControlModifier
: A Ctrl key on the keyboard is pressed.Qt.KeyboardModifier.AltModifier
: An Alt key on the keyboard is pressed.Qt.KeyboardModifier.MetaModifier
: A Meta key on the keyboard is pressed.Qt.KeyboardModifier.KeypadModifier
: A keypad button is pressed.Qt.KeyboardModifier.GroupSwitchModifier
: X11 only. A Mode_switch key on the keyboard is pressed.
delay (int) – after the event, delay the test for this milliseconds (if > 0).
- static keyToAscii(key)[source]
Auxiliary method that converts the given constant to its equivalent ascii.
- Parameters:
key (Qt.Key.Key_*) – one of the constants for keys in the Qt namespace.
- Return type:
str
- Returns:
the equivalent character string.
Note
This method is not available in PyQt.
—
Below are methods used to simulate sending mouse events to widgets.
- static mouseRelease(widget, button[, modifier=0[, pos=QPoint()[, delay=-1]]])[source]
Sends a mouse moves and clicks to a widget.
- Parameters:
widget (QWidget) – the widget that will receive the event
button (Qt.MouseButton) –
flags OR’ed together representing the button pressed. Possible flags are:
Qt.MouseButton.NoButton
: The button state does not refer to any button (see QMouseEvent.button()).Qt.MouseButton.LeftButton
: The left button is pressed, or an event refers to the left button. (The left button may be the right button on left-handed mice.)Qt.MouseButton.RightButton
: The right button.Qt.MouseButton.MidButton
: The middle button.Qt.MouseButton.MiddleButton
: The middle button.Qt.MouseButton.XButton1
: The first X button.Qt.MouseButton.XButton2
: The second X button.
modifier (Qt.KeyboardModifier) – flags OR’ed together representing other modifier keys also pressed. See keyboard modifiers.
pos (QPoint) – position of the mouse pointer.
delay (int) – after the event, delay the test for this milliseconds (if > 0).
Note
In the PySide bindings, the modifier argument is called stateKey.
TimeoutError
- class pytestqt.qtbot.TimeoutError[source]
Added in version 2.1.
Exception thrown by
pytestqt.qtbot.QtBot
methods.Access via
qtbot.TimeoutError
.
ScreenshotError
- class pytestqt.qtbot.ScreenshotError[source]
Added in version 4.1.
Exception thrown by
pytestqt.qtbot.QtBot.screenshot()
if taking the screenshot failed.Changed in version 4.2: Access via
qtbot.ScreenshotError
.
SignalEmittedError
- class pytestqt.qtbot.SignalEmittedError[source]
Added in version 1.11.
The exception thrown by
pytestqt.qtbot.QtBot.assertNotEmitted()
if a signal was emitted unexpectedly.
CallbackCalledTwiceError
SignalBlocker
- class pytestqt.wait_signal.SignalBlocker(timeout=5000, raising=True, check_params_cb=None)[source]
Returned by
pytestqt.qtbot.QtBot.waitSignal()
method.- Variables:
timeout (int) – maximum time to wait for a signal to be triggered. Can be changed before
wait()
is called.signal_triggered (bool) – set to
True
if a signal (or all signals in case ofMultipleSignalBlocker
) was triggered, orFalse
if timeout was reached instead. Untilwait()
is called, this is set toNone
.raising (bool) –
If
qtbot.TimeoutError
should be raised if a timeout occurred.Note
contrary to the parameter of same name in
pytestqt.qtbot.QtBot.waitSignal()
, this parameter does not consider the qt_default_raising ini option option.args (list) – The arguments which were emitted by the signal, or None if the signal wasn’t emitted at all.
Added in version 1.10: The args attribute.
- wait()
Waits until either a connected signal is triggered or timeout is reached.
- Raises:
ValueError – if no signals are connected and timeout is None; in this case it would wait forever.
MultiSignalBlocker
- class pytestqt.wait_signal.MultiSignalBlocker(timeout=5000, raising=True, check_params_cbs=None, order='none')[source]
Returned by
pytestqt.qtbot.QtBot.waitSignals()
method, blocks until all signals connected to it are triggered or the timeout is reached.- Variables identical to
SignalBlocker
: timeout
signal_triggered
raising
- wait()
Waits until either a connected signal is triggered or timeout is reached.
- Raises:
ValueError – if no signals are connected and timeout is None; in this case it would wait forever.
- Variables identical to
Record
- class pytestqt.logging.Record(msg_type, message, ignored, context)[source]
Hold information about a message sent by one of Qt log functions.
- Variables:
message (str) – message contents.
type (Qt.QtMsgType) – enum that identifies message type
type_name (str) –
type
as string:"QtInfoMsg"
,"QtDebugMsg"
,"QtWarningMsg"
or"QtCriticalMsg"
.log_type_name (str) – type name similar to the logging package:
INFO
,DEBUG
,WARNING
andCRITICAL
.when (datetime.datetime) – when the message was captured
ignored (bool) – If this record matches a regex from the “qt_log_ignore” option.
context – a namedtuple containing the attributes
file
,function
,line
. Can be None if no context is available for the message.
qapp fixture
- pytestqt.plugin.qapp(qapp_args, qapp_cls, pytestconfig)[source]
Fixture that instantiates the QApplication instance that will be used by the tests.
You can use the
qapp
fixture in tests which require aQApplication
to run, but where you don’t need fullqtbot
functionality.
- pytestqt.plugin.qapp_args(pytestconfig)[source]
Fixture that provides QApplication arguments to use.
You can override this fixture to pass different arguments to
QApplication
:@pytest.fixture(scope="session") def qapp_args(): return ["prog_name", "--arg=foo"]
Note that it can only be overridden once at session scope. It is not possible to override this per unit test since a QApplication cannot be destroyed and recreated within the same app.
The default value is a list with one element which is determined the same way as for
QApplication.applicationName()
, see qapp fixture for more information.