Search code examples
pythonqttimerpyqttestcase

QTimer's connection to timeout-method does not work in TestCases (Python)


I just finished a software and want to test it now with help of python's TestCase. The method test_show_video should start a QTimer. It is connected to test_run_iteration, which sums up an index up by one every 0,1 seconds. Before assert is called, the method has three seconds time to sum up the index, so it should be bigger then zero. But it is not. Does anybody have a clue? In fact, the timeout-connection to the timer seems to be wrong.

try:
    app = QtGui.QApplication(sys.argv)
except RuntimeError:
    app = QtCore.QCoreApplication.instance()

class TestProgressPresenter(TestCase):

    def test_show_video(self):

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.test_run_iteration)
        self.timer.start(100)
        self.index = 0

        millis = start_time = int(round(time.time() * 1000))

        while start_time + 3000 > millis:
            millis = int(round(time.time() * 1000))

        assert self.index > 0

    def test_run_iteration(self):
        self.index += 1

Solution

  • Here you are blocking the Qt event loop during the while loop for 3 seconds. Actually the timer's timeout signal is not called until control returns to the event loop and that's when the while is completed and test_show_video is finished.

    If you want the timer to get triggered you should make sure that the events are processed during the while loop checks. For that you can have some thing like :

    while start_time + 3000 > millis:
        millis = int(round(time.time() * 1000))
        QApplication.processEvents(QEventLoop.AllEvents)
    

    It can be even easier to wait for some seconds using a local event loop :

    self.loop = QtCore.QEventLoop()
    QTimer.singleShot(3000, loop.quit)
    loop.exec()
    
    assert self.index > 0