PyQt & unittest - Тестирование сигнала и слотов - PullRequest
4 голосов
/ 12 января 2010

У меня есть приложение pyqt, для которого я пишу юнит-тесты, и оно сильно зависит от сигналов и слотов. Чтобы правильно проверить это, я должен убедиться, что отправлены правильные сигналы.

Каков наилучший способ сделать это? Я вижу, что библиотека Qt имеет QSignalSpy, но я не могу найти ссылку на это в PyQt. Единственный вариант, который я могу придумать, - это издать эммит, например,

import testedmodule

def myemit(signal):
    ....

testedmodule.QObject.emit = myemit

но я надеюсь, что есть лучший способ.

Edit:
Мой модуль работает как поток, в этом случае переопределение emit экземпляра больше не работает после запуска потока, поэтому я обновил код выше, чтобы отразить это

Ответы [ 3 ]

1 голос
/ 14 января 2010

Это более сложная версия того, что я сам предложил, не обязательно лучшее решение для unittest, но я думаю, что оно будет интересно другим, кто сталкивается с этим:

Автор Карлос Шайдеггер в списке рассылки pyqt (http://thread.gmane.org/gmane.comp.python.pyqt-pykde/9242/focus=9245)

_oldConnect = QtCore.QObject.connect
_oldDisconnect = QtCore.QObject.disconnect
_oldEmit = QtCore.QObject.emit

def _wrapConnect(callableObject):
    """Returns a wrapped call to the old version of QtCore.QObject.connect"""
    @staticmethod
    def call(*args):
        callableObject(*args)
        _oldConnect(*args)
    return call

def _wrapDisconnect(callableObject):
    """Returns a wrapped call to the old version of QtCore.QObject.disconnect"""
    @staticmethod
    def call(*args):
        callableObject(*args)
        _oldDisconnect(*args)
    return call

def enableSignalDebugging(**kwargs):
    """Call this to enable Qt Signal debugging. This will trap all
    connect, and disconnect calls."""

    f = lambda *args: None
    connectCall = kwargs.get('connectCall', f)
    disconnectCall = kwargs.get('disconnectCall', f)
    emitCall = kwargs.get('emitCall', f)

    def printIt(msg):
        def call(*args):
            print msg, args
        return call
    QtCore.QObject.connect = _wrapConnect(connectCall)
    QtCore.QObject.disconnect = _wrapDisconnect(disconnectCall)

    def new_emit(self, *args):
        emitCall(self, *args)
        _oldEmit(self, *args)

    QtCore.QObject.emit = new_emit

просто вызовите enableSignalDebugging (emitCall = foo) и следите за своими сигналами до ты болен в животе:)

1 голос
/ 16 декабря 2015

Примечание. QSignalSpy имеет значение доступно как QtTest.QSignalSpy в PyQt5.

1 голос
/ 12 января 2010

Вы можете попробовать подключить слот к вашему сигналу, подготовить тест, а затем вызвать qApp.processEvents (), чтобы сигнал распространялся. Но я не думаю, что это на 100% надежно.

Жаль, что QSignalSpy на самом деле не является частью PyQt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...