unittest簡單介紹
- 單元測試框架
- 還可以適用WEB自動化測試用例的開發與執行
- 提供豐富的斷言方法
- 官方文檔:https://docs.python.org/zh-cn/3/library/unittest.html
unittest基礎使用
1 # 導入unittest模塊 2 import unittest 3 4 5 # 創建單元測試類,繼承unittest.TestCase 6 class testCase(unittest.TestCase): 7 8 def setUp(self): 9 print("case執行前") 10 11 def tearDown(self): 12 print("case執行后") 13 14 @classmethod 15 def setUpClass(cls): 16 print("對象執行前") 17 18 @classmethod 19 def tearDownClass(cls): 20 print("對象執行后") 21 22 # 測試用例 23 def test_01(self): 24 print("test01") 25 26 def test_02(self): 27 print("test02") 28 29 30 if __name__ == '__main__': 31 unittest.main()
運行結果
1 對象執行前 2 case執行前 3 test01 4 case執行后 5 case執行前 6 test02 7 case執行后 8 對象執行后 9 10 11 Ran 2 tests in 0.002s 12 13 OK
這里包含的知識點:
unittest.Testcase
- 自己創建的單元測試類都要繼承它,它是所有單元測試類的基類
setUp
- 用於每個測試用例執行前的初始化工作
- 所有類中方法的入參為 self ,定義實例變量也要 self.變量
tearDown
- 每個測試用例執行后的都會執行此方法
setUpClass
- 每個單元測試類運行前調用該方法,只會執行一次
- 屬於類方法,需要加上裝飾器 @classmethod
- 默認入參是 cls ,指的就是“類對象”本身,其實和self沒什么區別,用法一致
tearDownClass
- 每個單元測試類運行后調用該方法,只會執行一次
- 屬於類方法,需要加上裝飾器 @classmethod
測試用例
- 必須以“test_”開頭命名的方法,否則無法識別並執行
- 方法里面需要有斷言,才能在最后運行時有該用例的執行結果
- 可包含多個測試用例
unittest.main()
- 運行單元測試
- 該命令會搜索當前module 下所有以 test開頭的測試用例,並運行它們
- 執行順序是按照case的命名
unitteest提供的各種斷言方式
1 class testCase(unittest.TestCase): 2 3 def test_03(self): 4 # 斷言 - 是否為True 5 flag = True 6 self.assertTrue(flag, msg="測試失敗的信息,可不填") 7 8 def test_04(self): 9 # 斷言 - 是否為False 10 flag = False 11 self.assertFalse(flag) 12 13 def test_05(self): 14 # 斷言 - 提供的兩個參數是否相同(任意類型) 15 self.assertEqual("123", "123") # 字符串 16 self.assertEqual({"a": 1}, {"a": 1}) # 字典 17 self.assertEqual([1, 2], [1, 2]) # 列表 18 self.assertEqual((1, 2), (1, 2)) # 元組 19 self.assertEqual({1, 2}, {1, 2}) # 集合 20 21 def test_06(self): 22 # 斷言 - 列表是否相同 23 self.assertListtEqual([1, 2], [1, 2]) 24 25 def test_07(self): 26 # 斷言 - 字典是否相同 27 self.assertDictEqual({"a": 1}, {"a": 1}) 28 29 def test_08(self): 30 # 斷言 - 元組是否相同 31 self.assertTupleEqual((1, 2), (1, 2)) 32 33 def test_09(self): 34 # 斷言 - 集合是否相同 35 self.assertSetEqual({1, 2}, {1, 2})
這是比較常見的斷言方式,當然還有一些比較容易理解的斷言方式就沒有一一舉例啦,具體可以看看下面列表
| 方法 |
等同於python里面的寫法 |
| assertEqual(a, b) |
a == b |
| assertNotEqual(a, b) |
a != b |
| assertTrue(x) |
bool(x) is True |
| assertFalse(x) |
bool(x) is False |
| assertIs(a, b) |
a is b |
| assertIsNot(a, b) |
a is not b |
| assertIsNone(x) |
x is None |
| assertIsNotNone(x) |
x is not None |
| assertIn(a, b) |
a in b |
| assertNotIn(a, b) |
a not in b |
| assertIsInstance(a, b) |
isinstance(a, b) |
| assertNotIsInstance(a, b) |
not isinstance(a, b) |
| assertRegex(s, r) |
r.search(s) |
unittest測試用例跳過執行
1 class testCase(unittest.TestCase): 2 3 # 直接跳過 4 @unittest.skip("直接跳過") 5 def test_skip(self): 6 self.fail("shouldn't happen") 7 8 # 滿足condition則跳過 9 @unittest.skipIf(1 < 2, "滿足condition則跳過") 10 def test_skipIf(self): 11 print("skip if") 12 13 # 不滿足condition則跳過 14 @unittest.skipUnless(sys.platform.startswith("win"), "需要window平台才不會跳過") 15 def test_skipUnless(self): 16 print("skip Unless") 17 18 # 預計該測試用例會測試失敗 19 @unittest.expectedFailure 20 def test_fail(self): 21 self.assertEqual(1, 0, "broken") 22 23 # 方法體內跳出不執行case 24 def test_maybe_skipped(self): 25 if True: 26 self.skipTest("調用unittest的skipTest,在方法體內滿足某些條件則跳過該case") 27 pass
運行結果
1 Skipped: 調用unittest的skipTest,在方法體內滿足某些條件則跳過該case 2 3 Skipped: 直接跳過 4 5 Skipped: 滿足condition則跳過 6 skip Unless 7 8 9 Ran 5 tests in 0.010s 10 11 OK (skipped=3, expected failures=1)
跳過執行測試用例共有四種寫法
- @unittest.skip(reason) :跳過測試用例,reason 為測試被跳過的原因
- @unittest.skipIf(condition, reason) :當 condition 為真時,跳過測試用例。
- @unittest.skipUnless(condition, reason) :跳過測試用例,除非 condition 為真
- @unittest.expectedFailure :把測試用例標記為預計失敗;如果測試不通過,會被認為測試成功;如果測試通過了,則被認為是測試失敗
self.skipTest(reason)
在方法體內滿足某些條件下才跳過執行該測試用例
跳過執行測試用例注意點
- 被跳過的測試的 setUp() 和 tearDown() 不會被運行
- 只輸入 unittest.skip ,也可以正常跳過,不必寫reason
- 若輸入 unittest.skip() ,括號內必須寫reason,不得為空
- 可以針對單元測試類級別設置跳過執行(在class聲明上面直接加裝飾器即可),該單元測試類所有測試用例不會被執行
- 被跳過的類的 setUpClass() 和 tearDownClass() 不會被運行
- 當方法體內調用了 self.skipTest(reason) 方法,該測試用例還是會調用 setUp() 和 tearDown()
