Unittest 支持跳過單個測試用例方法甚至整個測試類,用於控制測試用例的運行。
Unittest 還可以將測試標記爲“預期失敗expected failure
”,即本來就應該失敗或者隨着程序版本的更新已不能正常運行的測試,標記後該用例失敗也不會認爲是測試結果上的失敗,也就是說不會將該用例的失敗計入測試結果。
跳過測試
跳過測試有兩種方式可以實現,一種是使用 skip() 裝飾器,裝飾類或者用例,另一種是直接調用 TestCase.skipTest() 。
裝飾器有三種:
-
@unittest.skip(reason)
無條件跳過當前裝飾的用例或類。reason 參數必填,用於描述跳過用例的理由。
-
@unittest.skipIf(condition, reason)
跳過當前測試,當 condition 參數爲 True 的時候,reason 用於描述跳過用例的理由。
-
@unittest.skipUnless(condition, reason)
與 skipIf() 相反。跳過當前測試,condition 參數不爲 True 的時候,reason 用於描述跳過用例的理由。
這次爲了演示,將前面案例中的 4 個用例放在一個文件中,分別演示三種 skip:
import unittest
from add import add
is_smoke = False
class TestAddOne(unittest.TestCase):
@unittest.skip('直接跳過用例演示!') # => skip
def test_add_int(self):
'''測試int相加'''
result = add(5, 100)
print('整數相加結果:', result)
self.assertEqual(result, 105, '整數相加錯誤')
@unittest.skipIf(is_smoke, '非冒煙用例,冒煙時不執行') # => skipIf
def test_add_str(self):
'''測試str相加'''
result = add('5', '6')
print('字符串相加結果:', result)
self.assertEqual(result, '56', '字符串相加錯誤')
class TestAddTwo(unittest.TestCase):
@unittest.skipUnless(is_smoke, '冒煙用例,只在冒煙時執行') # => skipUnless
def test_add_list(self):
result = add(['1', '2'], ['a', 'b'])
print('列表相加結果:', result)
self.assertEqual(result, ['1','2','a','b'], '列表相加錯誤')
def test_add_tuple(self):
result = add((1,2), (3,4))
print('元組相加結果:', result)
self.assertEqual(result, (1,2,3,4), '元組相加錯誤')
if __name__ == "__main__":
unittest.main()
當 is_smoke = True
時,會跳過 test_add_int
和 test_add_str
。skip 裝飾的 test_add_int
始終會跳過,test_add_str
由 skipIf 裝飾,當 is_smoke 爲 True 時跳過。
ss..
-------------------------------------
Ran 4 tests in 0.001s
OK (skipped=2)
列表相加結果: ['1', '2', 'a', 'b']
元組相加結果: (1, 2, 3, 4)
s
表示跳過的用例,skipped=2
跳過兩個用例。
當 is_smoke = False
時,會跳過 test_add_int
和 test_add_list
。skip 裝飾的 test_add_int
始終會跳過,test_add_list
由 skipUnless 裝飾當 is_smoke 爲 False 時跳過。
s.s.
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK (skipped=2)
字符串相加結果: 56
元組相加結果: (1, 2, 3, 4)
裝飾類與裝飾用例類似,並且直接跳過整個類中的所有用例:
@unittest.skip('演示跳過裝飾類')
class TestAddTwo(unittest.TestCase):
pass
自己試試!
除了使用裝飾器跳過外,還可以使用 TestCase.skipTest() 直接在 setUp() 方法或者用例內部跳過。
在 setUp() 中使用會跳過整個測試類。
import unittest
from add import add
is_smoke = True
class TestAddOne(unittest.TestCase):
def setUp(self):
if is_smoke:
self.skipTest('直接跳過演示') # => 直接調用skipTest()
def test_add_int(self):
'''測試int相加'''
result = add(5, 100)
print('整數相加結果:', result)
self.assertEqual(result, 105, '整數相加錯誤')
def test_add_str(self):
'''測試str相加'''
if is_smoke:
self.skipTest('非冒煙用例,冒煙時不執行') # => 在用例內調用
result = add('5', '6')
print('字符串相加結果:', result)
self.assertEqual(result, '56', '字符串相加錯誤')
if __name__ == "__main__":
unittest.main()
上面演示了在 setUp() 中使用 skipTest() 跳過整個類,在用例中使用跳過當前用例。
標記預期失敗
標記預期失敗,用於針對肯定會失敗的用例,該用例依然會運行,只是就算未通過也不會計入失敗的用例。但是如果該用例運行成功,則會標識用例失敗。
我們將 TestAddTwo 中的最後一個用例標記爲預期失敗:
class TestAddTwo(unittest.TestCase):
@unittest.expectedFailure # => 注意,沒有括號
def test_add_tuple(self):
result = add((1,2), (3,4))
print('元組相加結果:', result)
self.assertEqual(result, (1,1,3,4), '元組相加錯誤')
運行後的結果爲:
...x
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK (expected failures=1)
整數相加結果: 105
字符串相加結果: 56
列表相加結果: ['1', '2', 'a', 'b']
元組相加結果: (1, 2, 3, 4)
x
,表示標記預期失敗,三個成功,一個預期失敗。test_add_tuple
用例結果是故意寫成失敗的,但是並沒有標記爲失敗,只是標記爲 x
。