waitCallback: Waiting for methods taking a callback

Added in version 3.1.

Some methods in Qt (especially QtWebEngine) take a callback as argument, which gets called by Qt once a given operation is done.

To test such code, you can use qtbot.waitCallback which waits until the callback has been called or a timeout is reached.

The qtbot.waitCallback() method returns a callback which is callable directly.

For example:

def test_js(qtbot):
    page = QWebEnginePage()
    with qtbot.waitCallback() as cb:
        page.runJavaScript("1 + 1", cb)
    cb.assert_called_with(2)  # result of the last js statement

Anything following the with block will be run only after the callback has been called.

If the callback doesn’t get called during the given timeout, qtbot.TimeoutError is raised. If it is called more than once, qtbot.CallbackCalledTwiceError is raised.

raising parameter

Similarly to qtbot.waitSignal, you can pass a raising=False parameter (or set the qt_default_raising ini option) to avoid raising an exception on timeouts. See waitSignal: Waiting for threads, processes, etc. for details.

Getting arguments the callback was called with

After the callback is called, the arguments and keyword arguments passed to it are available via .args (as a list) and .kwargs (as a dict), respectively.

In the example above, we could check the result via:

assert cb.args == [2]
assert cb.kwargs == {}

Instead of checking the arguments by hand, you can use .assert_called_with() to make sure the callback was called with the given arguments:

cb.assert_called_with(2)