PyQt& unittest - 测试信号和插槽

时间:2010-01-11 22:14:28

标签: python pyqt unit-testing

我有一个pyqt应用程序,我正在编写单元测试,它很大程度上依赖于信号和插槽。为了正确测试它,我必须检查是否发送了正确的信号。

最好的方法是什么?我看到Qt库有一个QSignalSpy,但我在PyQt中找不到任何对它的引用。我能想到的唯一选择是模拟发射,例如

import testedmodule

def myemit(signal):
    ....

testedmodule.QObject.emit = myemit

但我希望有更好的方法。

编辑:
我的模块作为一个线程运行,在这种情况下,在启动线程后覆盖一个实例的发射不再有效,所以我更新了上面的代码以反映这一点。

3 个答案:

答案 0 :(得分:1)

您可以尝试将插槽连接到信号,准备测试,然后调用qApp.processEvents()让信号传播。但我不认为它是100%可靠的。

遗憾的是,QSignalSpy确实不属于PyQt。

答案 1 :(得分:1)

这是我自己建议的更精细的版本,不一定是单元测试的最佳解决方案,但我认为其他人会对此感兴趣:

Carlos Scheidegger在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)并监视你的信号直到 你生病了!)

答案 2 :(得分:1)

注意在PyQt5中,QSignalSpy为availableQtTest.QSignalSpy