我正在构建一个基于PySide 1.1.0的应用程序,并且一直在寻找好的示例来查看我的应用程序的单元和功能测试。我希望能够对UI进行功能测试(模拟点击,按键等),改变UI布局的UI插槽的单元测试(可能使用部分模拟的发送器和接收器),以及单元测试涉及小部件的代码,但不需要渲染任何窗口。
作为一个例子,当项目被添加到向QTreeView提供数据的模型(QAbstractItemModel派生对象)时,我动态创建菜单栏中一个菜单的子菜单。模型和子菜单必须保持同步,所以我希望能够编写一个单元测试,将数据提交给管理模型和子菜单的控制器,并断言模型和子菜单都已正确更新。
如果可以避免,我宁愿不必在我的测试代码中设置QApplication。当我只关心验证小部件中的数据结构而不是它们的可视化时,我也不想显示任何窗口。
我在http://www.pyside.org或Google搜索中找不到任何合适的值。有没有人有任何经验或知道我应该看的好样本代码?
答案 0 :(得分:30)
我现在一直在玩单元测试pyside代码并得出结论,将python的unittest
模块与qt的QTest
模块结合使用效果非常好。
您必须实例化QApplication
对象,但不需要运行其exec_
方法,因为您不需要运行事件循环。
这是一个关于我如何测试对话框中的QCheckBox
是否能完成它应该做的事情的示例:
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(), "")
这完全适用于屏幕外,包括点击小工具并在QLineEdit
中输入文字。
以下是我测试(相当简单)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
我希望这有点帮助。
答案 1 :(得分:2)
就我而言,我收到错误'QPixmap:必须在QPaintDevice之前构建一个QApplication'。
如果您需要为测试提供QApplication实例(例如使用QPixmap),这是一种方法。只需创建一个单例,就可以确保只有一个QApplication实例。
这可以作为PySide源代码中的测试帮助。
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()
然后继承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)
希望这会有所帮助