Unit and functional testing a PySide-based application?

后端 未结 2 1700
甜味超标
甜味超标 2020-12-07 17:01

I\'m building a PySide 1.1.0-based application, and have been looking for good examples to look at for unit and functional testing my application. I want to be able to do f

相关标签:
2条回答
  • 2020-12-07 17:28

    I've been playing around a bit now with unit-testing pyside code and came to the conclusion that combining python's unittest module with qt's QTest module works pretty good.

    You will have to have a QApplication object instantiated, but you do not need to run its exec_ method, because you don't need the event loop to be running.

    Here is an example on how I test if a QCheckBox in a dialog does what it is supposed to do:

    class Test_PwsAddEntryDialog(TestCase):
        """Tests the class PwsAddEntryDialog."""
    
        def test_password_strength_checking_works(self):
            """Tests if password strength checking works, if the corresponding check
            box is checked.
            """
            d = PwsAddEntryDialog()
            # test default of internal flag
            self.assertFalse(d.testPasswordStrength)
            # type something
            QTest.keyClicks(d.editSecret, "weak", 0, 10)
            # make sure that entered text is not treated as a password
            self.assertEqual(d.labelPasswordStrength.text(), "")
            # click 'is password' checkbox
            QTest.mouseClick(d.checkIsPassword, Qt.LeftButton)
            # test internal flag changed
            self.assertTrue(d.testPasswordStrength)
            # test that label now contains a warning
            self.assertTrue(d.labelPasswordStrength.text().find("too short") > 0)
            # click checkbox again
            QTest.mouseClick(d.checkIsPassword, Qt.LeftButton)
            # check that internal flag once again changed
            self.assertFalse(d.testPasswordStrength)
            # make sure warning disappeared again
            self.assertEqual(d.labelPasswordStrength.text(), "")
    

    This completely works off-screen, involves clicking widgets and typing text in a QLineEdit.

    Here is how I test a (rather simple) QAbstractListModel:

    class Test_SectionListModel(TestCase):
        """Tests the class SectionListModel."""
    
        def test_model_works_as_expected(self):
            """Tests if the expected rows are generated from a sample pws file
            content.
            """
            model = SectionListModel(SAMPLE_PASSWORDS_DICT)
            l = len(SAMPLE_PASSWORDS_DICT)
            self.assertEqual(model.rowCount(None), l)
            i = 0
            for section in SAMPLE_PASSWORDS_DICT.iterkeys():
                self.assertEqual(model.data(model.index(i)), section)
                i += 1
    

    I hope this helps a littlebit.

    0 讨论(0)
  • 2020-12-07 17:46

    In my case, I was getting an error 'QPixmap: Must construct a QApplication before a QPaintDevice'.

    If you need to have a QApplication instance for your tests (eg use QPixmap), here's one way to do it. Just create a singleton so that you are ensured one and only one QApplication instance.

    This is buried as a helper for tests in the PySide source.

    import unittest
    
    from PySide.QtGui import QApplication
    _instance = None
    
    class UsesQApplication(unittest.TestCase):
        '''Helper class to provide QApplication instances'''
    
        qapplication = True
    
        def setUp(self):
            '''Creates the QApplication instance'''
    
            # Simple way of making instance a singleton
            super(UsesQApplication, self).setUp()
            global _instance
            if _instance is None:
                _instance = QApplication([])
    
            self.app = _instance
    
        def tearDown(self):
            '''Deletes the reference owned by self'''
            del self.app
            super(UsesQApplication, self).tearDown()
    

    and then subclass UsesQApplication

    from PySide import QtGui
    
    class Test(UsesQApplication):
    
        def setUp(self):
            #If you override setup, tearDown, make sure
            #to have a super call
            super(TestFilterListItem, self).setUp()
    
        def tearDown(self):
            super(TestFilterListItem, self).tearDown()
    
        def testName(self):
            pix = QtGui.QPixmap(20,20)
            self.assertTrue(True)
    

    hope this helps

    0 讨论(0)
提交回复
热议问题