2015-10-03 16 views
5

Tôi chỉ đang sử dụng không giới hạn trong một thời gian ngắn. Tôi đang sử dụng Jython 2.7.10 "phát hành cuối cùng"Tôi làm cách nào để sử dụng unittest.TestResult?

Trong các tài liệu Python 2.7 giải thích TestResult nó nói:

Các phương pháp sau đây của lớp TestResult được sử dụng để duy trì cấu trúc dữ liệu nội bộ, và có thể được mở rộng trong các lớp con để hỗ trợ các yêu cầu báo cáo bổ sung. Điều này đặc biệt hữu ích trong các công cụ xây dựng hỗ trợ báo cáo tương tác trong khi các thử nghiệm là đang chạy.

startTest (thử nghiệm) ... stopTest (thử nghiệm) ... startTestRun() ... stopTestRun() ¶

Đó là những gì tôi muốn làm ... nhưng tôi không thể làm việc ra cách bạn sử dụng TestResult. Dưới đây là một SSCCE ...

import unittest 

class TestResultX(unittest.TestResult): 
    def startTest(self, test): 
     print('# blip') 
     unittest.TestResult.startTest(self, test) 
    def stopTest(self, test): 
     print('# blop') 
     unittest.TestResult.stopTest(self, test) 
    def startTestRun(self): 
     print('# blep') 
     unittest.TestResult.startTestRun(self) 
    def stopTestRun(self): 
     print('# blap') 
     unittest.TestResult.stopTestRun(self) 

class TestCaseX(unittest.TestCase): 
    def test_nonsense(self): 
     print('# wotcha') 
     self.assertTrue(False) 

    def run(self, test_result=None): 
     print('# spoons starting...') 

     test_result = TestResultX() 
     unittest.TestCase.run(self, test_result) 

     print('# ...spoons ended, tr %s' % (test_result, )) 

unittest.main() 

Kết quả trong:

# spoons starting... 

---------------------------------------------------------------------- 
Ran 0 tests in 0.015s 

OK 
# blip 
# wotcha 
# blop 
# ...spoons ended, tr <__main__.TestResultX run=1 errors=0 failures=1> 

Câu hỏi:

  • Tại sao nó nói 0 tests?
  • Tại sao blepblap (bắt đầu và kết thúc chạy) không được in?

Trên một lưu ý tổng quát hơn:

  1. Có thể ai đó có thể trỏ đến một hướng dẫn/cuốn sách hay giải thích "sử dụng hợp lý"/"thực hành tốt" khi nói đến TestResult, TestRunner, TestLoader, vv Tôi đã nhận "TDD với Python", nhưng nó dường như không giải thích được điều này.

  2. Có thể ai đó có thể cho tôi biết tại sao unittest2 thường dường như được sử dụng thay vì bỏ qua?

phụ lục

Sau những nỗ lực Omar Diab tại nhìn vào mã nguồn tôi đã cố gắng này:

def run(self, *args, **kvargs): 
    result = self.defaultTestResult() 
    startTestRun = getattr(result, 'startTestRun', None) 
    logger.info('# calling superclass run... startTestRun? %s' % (startTestRun,)) 
    unittest.TestCase.run(self, *args, **kvargs ) 
    logger.info('# ... superclass run ended') 

Đáng tiếc là mỗi phương pháp test_XXX sau đó đã đưa:

# calling superclass run... startTestRun? <bound method TestResult.startTestRun of <unittest.result.TestResult run=0 errors=0 failures=0>> 

setUp for test_that_stuff_happened (__main__.xx_FT) 

tearDown for test_that_stuff_happened (__main__.xx_FT) 
end tearDown... 
. # ... superclass run ended 
+0

Tôi đang chạy vào điều này — phải nói, tài liệu cho tất cả điều này là khá khủng khiếp ... –

Trả lời

0

unittest2 là một backport của các tính năng mới nhất cho Python 2.4-2.6 Nó có nghĩa là, nếu bạn có một số tập lệnh Python 2.4-2.6 và muốn chạy trong 2.7 và phiên bản mới hơn, bạn nên sử dụng.

bạn có thể tìm thông tin chi tiết ở đây: https://docs.python.org/2/library/unittest.html

+1

Cảm ơn bạn đã giải thích unittest2. Liên kết đó là tài liệu Python 2.7 mà tôi trích dẫn và không đủ giải thích. –

1

Wow, không có câu trả lời. Tôi ngạc nhiên.

Đây là một hack mà hầu hết mọi người không có nghi ngờ có thể làm việc ra cho bản thân, nếu bạn muốn những thứ xảy ra vào lúc bắt đầu chạy và kết thúc của thời gian:

Subclass TestCase, theo:

def setUp(self): 
    if not hasattr(unittest.TestCase, 'app'): 
     unittest.TestCase.app = MyApp() 
     def shutdown_func(): 
      pass # do any end-of-run stuff here 
     atexit.register(shutdown_func) 
     pass # do any start-of-run stuff here 
    self.app = unittest.TestCase.app 

Sau đó, làm cho tất cả TestCases lớp con của bạn từ một này ...

điểm phúc, nếu bạn muốn điều này xảy ra, rằng ứng dụng của bạn chỉ được xây dựng một lần. Xử lý trách nhiệm đảm bảo rằng nó là "nguyên sơ" cho mỗi liên tiếp setUp là tùy thuộc vào bạn tất nhiên. Rõ ràng bạn có thể sử dụng setUpClass thay vào đó nhưng sau đó bạn không có quyền truy cập vào phiên bản TestCase.

0

Tôi gặp vấn đề tương tự, vì vậy tôi đã xem xét mã nguồn.

Kiểm tra unittest.TextTestRunnerunittest.TestCase, có vẻ như startTestRun()stopTestRun() được gọi theo cách thủ công. Trong unittest.TextTestRunner, nó hoạt động như sau:

def run(self, test): 
    # ... 
    startTestRun = getattr(result, 'startTestRun', None) 
    if startTestRun is not None: 
     startTestRun() 
    # ... 

và trong trường hợp của bạn, unittest.TestCase, nó là như vậy:

def run(self, result=None): 
    orig_result = result 
    if result is None: 
     result = self.defaultTestResult() 
     startTestRun = getattr(result, 'startTestRun', None) 
     if startTestRun is not None: 
      startTestRun() 
    # ... 

Vì vậy, nó trông giống như startTestRun chỉ thực sự được gọi bằng TestCase.run() nếu bạn không vượt qua trong result. Bạn đang đi qua số result, vì vậy nó không xảy ra.

Điều này có vẻ giống như một lỗi đối với tôi! Nhưng về cơ bản nó có nghĩa là bạn có thể mở rộng TestCase hoặc TestSuite, reimplement phương thức chạy, và sau đó gọi những phương thức đó bằng tay; hoặc chỉ gọi cho họ ngoài những phương thức tương ứng run.

Hy vọng điều này sẽ hữu ích!

+0

Cảm ơn bạn đã xem mã nguồn. Nên tự mình làm vậy, tất nhiên rồi! Rất tiếc, đề xuất của bạn về việc tái kỹ thuật phương pháp chạy không hiệu quả đối với tôi. Xem phụ lục tôi đang làm cho bài đăng gốc ... –

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