2012-09-25 61 views
8

我想將一個自定義斷言方法添加到TestCase子類。我試圖從unittest模塊中複製我的實現,以便儘可能匹配常規TestCase的行爲。 (我寧願只是委託給self.assertEqual(),但這會導致更多的回溯噪音,請參閱下文)。unittest模塊似乎在報告失敗的斷言時會自動隱藏其實施的一些內部細節。如何隱藏我的堆棧框架在TestCase子類中?

import unittest 

class MyTestCase(unittest.TestCase): 
    def assertLengthIsOne(self, sequence, msg=None): 
     if len(sequence) != 1: 
      msg = self._formatMessage(msg, "length is not one") 
      raise self.failureException(msg) 

class TestFoo(MyTestCase): 
    seq = (1, 2, 3, 4, 5) 

    def test_stock_unittest_assertion(self): 
     self.assertEqual(len(self.seq), 1) 

    def test_custom_assertion(self): 
     self.assertLengthIsOne(self.seq) 


unittest.main() 

的這個輸出是這樣:

[email protected] $ python unittest-demo.py 
FF 
====================================================================== 
FAIL: test_custom_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "unittest-demo.py", line 16, in test_custom_assertion 
    self.assertLengthIsOne(self.seq) 
    File "unittest-demo.py", line 7, in assertLengthIsOne 
    raise self.failureException(msg) 
AssertionError: length is not one 

====================================================================== 
FAIL: test_stock_unittest_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "unittest-demo.py", line 13, in test_stock_unittest_assertion 
    self.assertEqual(len(self.seq), 1) 
AssertionError: 5 != 1 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

FAILED (failures=2) 

注意,定製的斷言方法導致與兩個框架,一個方法本身內的堆棧跟蹤,而庫存unittest方法僅具有一個框架,用戶代碼中的相關行。我怎樣才能將這個框架隱藏行爲應用於我自己的方法?

回答

14

這個問題被回答了by Peter Otten on comp.lang.python

將MyTestCase移動到單獨的模塊中,並定義一個全局變量__unittest = True

$ cat mytestcase.py 
import unittest 

__unittest = True 

class MyTestCase(unittest.TestCase): 
    def assertLengthIsOne(self, sequence, msg=None): 
     if len(sequence) != 1: 
      msg = self._formatMessage(msg, "length is not one") 
      raise self.failureException(msg) 

$ cat mytestcase_demo.py 
import unittest 
from mytestcase import MyTestCase 

class TestFoo(MyTestCase): 
    seq = (1, 2, 3, 4, 5) 

    def test_stock_unittest_assertion(self): 
     self.assertEqual(len(self.seq), 1) 

    def test_custom_assertion(self): 
     self.assertLengthIsOne(self.seq) 

if __name__ == "__main__": 
    unittest.main() 

$ python mytestcase_demo.py 
FF 
====================================================================== 
FAIL: test_custom_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "mytestcase_demo.py", line 11, in test_custom_assertion 
    self.assertLengthIsOne(self.seq) 
AssertionError: length is not one 

====================================================================== 
FAIL: test_stock_unittest_assertion (__main__.TestFoo) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "mytestcase_demo.py", line 8, in test_stock_unittest_assertion 
    self.assertEqual(len(self.seq), 1) 
AssertionError: 5 != 1 

---------------------------------------------------------------------- 
Ran 2 tests in 0.000s 

FAILED (failures=2) 
$ 
+0

我不能相信這個問題/答案沒有得到更多的投票!偉大的信息,以及爲什麼我<3 SO。 – dbn

+0

該解決方案非常有用! –

+0

不確定是否更改了python.org上的pipermail,但正確鏈接到Peter的解決方案是https://mail.python.org/pipermail/python-list/2012-October/632386.html。除此之外,非常感謝你的指針,真的幫助了我。 –

相關問題