mardi 3 avril 2018

How can i test the connection between two QDialogs, when one QDialog is waiting for the other?

I started to write some tests for my PySide application. For unit testing i use the unittests module from python in combination with QTest to simulate button clicks.

Everythings seems to work pretty good until i tried to test QDialog communications.

Assuming we have following dialogs: MainDialog, PasswordDialog and TableDialog

The application starts with the MainDialog. With a button you can open the TableDialog but first of all you need to enter a password in the PasswordDialog.

For example a user could do this:

  1. Start Application -> MainDialog is shown.

  2. Click on Table button -> PasswordDialog pops up.

  3. User enters correct password and presses submit -> TableDialog is shown now.

Implementation of this communication:

In MainDialog

# slot for table button
def openTableButtonClicked(self):
    exitStatus= self.executeDialog(PasswordDialog())
    if(exitStatus == QtGui.QDialog.Accepted):
        self.executeDialog(TableDialog())

# needed to save running dialog for testing
def executeDialog(self, dialog)
    self.activeDialog = dialog
    exitStatus = dialog.exec_()
    self.activeDialog = self
    return exitStatus

Test function

def test_dialogCommunication(self):
    # self.mainDialog is created in a setUp function of unittets module
    QTest.mouseClick(self.mainDialog.openTableButton, Qt.LeftButton)
    self.assertIsInstance(self.mainDialog.activeUiDialog, PasswordDialog) # check if password dialog is shown

    # Assuming enterCorrectPasswordAndSubmit is implemented in PasswordDialog
    self.mainDialog.activeDialog.enterCorrectPasswordAndSubmit()
    self.assertIsInstance(self.mainDialog.activeUiDialog, TableDialog)

Sadly this test function doesn't work because the main thread is "caged" in QDialog.exec_() thus the assert functions are never reached. ( QTest.mouseClick(self.mainDialog.openTableButton, Qt.LeftButton) is calling MainDialog.openTableButtonClicked()->executeDialog()->dialog.exec_() )

So i tried to call the QTest.mouseClick in another thread using pythons threading module:

def test_dialogCommunication(self):
    t1 = threading.Thread(target=self.helper)
    t1.start()
    self.assertIsInstance(self.mainDialog.activeUiDialog, PasswordDialog)
    self.mainDialog.activeDialog.enterCorrectPasswordAndSubmit()
    t1.join()
    ....

def helper(self):
    QTest.mouseClick(self.mainDialog.openTableButton, Qt.LeftButton)

But this doesn't get the job done either because the QTest.mouseClick function doesn't seem to work outside the main thread (i think).

My Question:

How can i test the connection between two QDialogs, when one QDialog is waiting for the other? Particularly: How can i change values/click buttons on the UI (like enterCorrectPasswordAndSubmit does) of QDialogs that called the exec_() function.

Aucun commentaire:

Enregistrer un commentaire