pytest-dev / pytest-dev/pytest-qt

Incorrect waitSignal + connect

Open
#607 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
455
Forks
72
Avg merge
12h 26m
Merged PRs (30d)
1

Description

import pytest
from PySide6.QtCore import QObject, Signal, QThread, QTimer
from PySide6.QtWidgets import QApplication
from pytestqt.qtbot import QtBot


@pytest.fixture(scope="session", autouse=True)
def qapp_instance():
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    return app


class MySignalEmitter(QObject):
    signal_A_emitted = Signal(str, int)
    signal_B_emitted = Signal(bool, float)

    def __init__(self):
        super().__init__()
        self._thread = QThread()
        self.moveToThread(self._thread)
        self._thread.started.connect(self._keep_thread_alive)

    def _keep_thread_alive(self):

        pass

    def start(self):
        if not self._thread.isRunning():
            self._thread.start()

    def stop(self):
        if self._thread.isRunning():
            self._thread.quit()
            self._thread.wait(500)

    def emit_signal_A(self, message: str, code: int):

        if self._thread.isRunning():
            QTimer.singleShot(0, lambda: self.signal_A_emitted.emit(message, code))
        else:
            self.signal_A_emitted.emit(message, code)


    def emit_signal_B(self, status: bool, value: float):
        if self._thread.isRunning():
            QTimer.singleShot(0, lambda: self.signal_B_emitted.emit(status, value))
        else:
            self.signal_B_emitted.emit(status, value)




def test_signals(qtbot: QtBot):
    emitter = MySignalEmitter()
    emitter.start()

    with qtbot.waitSignal((emitter.signal_A_emitted, "A"), timeout=3000, raising=True) as blocker:
        blocker.connect((emitter.signal_B_emitted, "B"))
        emitter.emit_signal_B(True, 3.14)

    assert blocker.signal_triggered is True
    assert blocker.args == [True, 3.14]
    assert blocker.signal_name == "B"

    with qtbot.waitSignal((emitter.signal_A_emitted, "A"), timeout=3000, raising=True) as blocker:
        blocker.connect((emitter.signal_B_emitted, "B"))
        emitter.emit_signal_A("message", 0)

    assert blocker.signal_triggered is True
    assert blocker.args == ["message", 0]
    assert blocker.signal_name == "A"

    emitter.stop()

will fail with:

>       assert blocker.signal_name == "A"
E       AssertionError: assert 'B' == 'A'
E
E         - A
E         + B

src\tests\issue_pytestqt_test.py:73: AssertionError

what is the workaround to have an OR condition?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the example in src\tests\issue_pytestqt_test.py, focusing on the two qtbot.waitSignal calls and blocker.connect usage. Read the waitSignal and blocker connection behavior in pytest-qt, then establish the supported way to wait for either signal and verify both signal_name and args cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.