2012-06-21 29 views
16

Tôi đang xây dựng một ứng dụng dựa trên PySide 1.1.0 và đang tìm kiếm các ví dụ tốt để xem xét đơn vị và chức năng kiểm tra ứng dụng của tôi. Tôi muốn có thể thực hiện kiểm tra chức năng của giao diện người dùng (mô phỏng nhấp chuột, nhấn phím, v.v.), kiểm tra đơn vị các khe UI thay đổi bố cục của giao diện người dùng (có thể sử dụng người gửi và người nhận được mô phỏng một phần), cũng như đơn vị kiểm tra mã liên quan đến các tiện ích con nhưng không yêu cầu bất kỳ cửa sổ nào được hiển thị. Một ví dụ, tôi tự động tạo menu phụ của một menu trong thanh thực đơn khi một mục được thêm vào một mô hình (đối tượng có nguồn gốc từ QAbstractItemModel) cung cấp dữ liệu cho một QTreeView. Mô hình và menu phụ phải được đồng bộ, vì vậy tôi muốn có thể viết một bài kiểm tra đơn vị gửi dữ liệu đến bộ điều khiển quản lý mô hình và menu phụ, và xác nhận rằng cả mô hình và menu phụ đều được cập nhật đúng.Đơn vị và chức năng thử nghiệm một ứng dụng dựa trên PySide?

Tôi muốn KHÔNG phải thiết lập QApplication trong mã thử nghiệm của mình nếu tôi có thể tránh được. Tôi cũng không muốn hiển thị bất kỳ cửa sổ nào khi tôi chỉ quan tâm đến việc xác thực cấu trúc dữ liệu trong các tiện ích, chứ không phải hiển thị trực quan của chúng.

Tôi không thể tìm thấy bất kỳ giá trị phù hợp nào tại số http://www.pyside.org hoặc trong các tìm kiếm trên Google của tôi. Có ai có bất kỳ kinh nghiệm hoặc biết mã mẫu tốt mà tôi nên xem xét?

+0

Tôi cũng đánh giá cao intereseted trong một giải pháp cho điều này, như tôi đang phải đối mặt với những vấn đề chính xác cùng – Chris

+1

Bạn đã thấy: http : //johnnado.com/pyqt-qtest-example/ Đó là PyQt, nhưng khá giống nhau. – neuronet

Trả lời

29

Tôi đã chơi xung quanh một chút bây giờ với mã pyside đơn vị thử nghiệm và đi đến kết luận rằng việc kết hợp mô-đun python của unittest với module qt của QTest hoạt động khá tốt.

Bạn sẽ phải có đối tượng QApplication được khởi tạo, nhưng bạn không cần chạy phương thức exec_ của mình, vì bạn không cần vòng lặp sự kiện để chạy.

Dưới đây là một ví dụ về cách tôi kiểm tra nếu một QCheckBox trong một hộp thoại hiện những gì nó có nghĩa vụ phải làm:

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(), "") 

này hoàn toàn làm việc tắt màn hình, bao gồm cách nhấn vào widget và văn bản gõ vào một QLineEdit.

Sau đây là cách tôi thử nghiệm một (chứ không phải đơn giản) 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 

Tôi hy vọng điều này sẽ giúp rất littlebit.

2

Trong trường hợp của tôi, tôi gặp lỗi 'QPixmap: Phải tạo QApplication trước QPaintDevice'.

Nếu bạn cần có một phiên bản QApplication cho các bài kiểm tra của bạn (ví dụ: sử dụng QPixmap), đây là một cách để thực hiện. Chỉ cần tạo một singleton để bạn được đảm bảo một và chỉ một cá thể QApplication.

Điều này được chôn cất như một người trợ giúp cho các thử nghiệm trong nguồn 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() 

và sau đó UsesQApplication lớp con

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) 

hy vọng điều này giúp

+7

Tôi chỉ làm 'nếu QtGui.qApp == Không có: QtGui.QỨng dụng ([]) 'ở đầu mỗi mô-đun thử nghiệm sử dụng QtGui. – strubbly

Các vấn đề liên quan