Unittest-用例執行策略:跳過用例和預期失敗

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_inttest_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_inttest_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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章