Reference:
廖雪峰-單元測試
單元測試主要用來對一個方法同诫、一個類或者一個模塊進行檢查的∽迦牛基于測試驅動開發(fā)(TDD)的思想,為了讓編寫的某個模塊的代碼能夠通過提前寫好的測試代碼击奶。
單元測試可考慮的級別https://www.zhihu.com/question/27313846/answer/120164282
我給自己的單元測試設置了5個級別:
- Level1:正常流程可用,即一個函數(shù)在輸入正確的參數(shù)時吐根,會有正確的輸出
- Level2:異常流程可拋出邏輯異常正歼,即輸入?yún)?shù)有誤時,不能拋出系統(tǒng)異常拷橘,而是用自己定義的邏輯異常通知上層調用代碼其錯誤之處
- Level3:極端情況和邊界數(shù)據(jù)可用局义,對輸入?yún)?shù)的邊界情況也要單獨測試,確保輸出是正確有效的
- Level4:所有分支冗疮、循環(huán)的邏輯走通萄唇,不能有任何流程是測試不到的
- Level5:輸出數(shù)據(jù)的所有字段驗證,對有復雜數(shù)據(jù)結構的輸出术幔,確保每個字段都是正確的
unittest
官方文檔地址:https://docs.python.org/zh-cn/3/library/unittest.html#module-unittest
先來看一下unittest的工作原理:Python必會的單元測試框架 —— unittest
總結一下原理:
寫好TestCase另萤,然后由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運行TestSuite诅挑,運行的結果保存在TextTestResult中四敞,我們通過命令行或者unittest.main()執(zhí)行時,main會調用TextTestRunner中的run來執(zhí)行拔妥,或者我們可以直接通過TextTestRunner來執(zhí)行用例忿危。這里加個說明,在Runner執(zhí)行時没龙,默認將執(zhí)行結果輸出到控制臺铺厨,我們可以設置其輸出到文件,在文件中查看結果
unittest使用步驟:
1.創(chuàng)建一個測試用例類繼承unittest.TestCase類
2.測試方法名稱以test開頭硬纤,在測試方法內調用方法對預期輸出和實際輸出進行比較解滓,方法包括不限于assertEqual(),assertTrue(),assertFalse(),assertRaises()。測試方法的執(zhí)行順序是按test后字母的順序執(zhí)行的筝家。
3.使用unittest.main()來運行測試腳本洼裤,也可以通過在命令行使用python -m unittest 測試文件名.測試用例類名的方式進行調用,如下代碼溪王,我們使用python -m unittest -v testmodel.MyUnittest進行調用(其中-v可以直觀的表現(xiàn)出每一個方法測試時的運行)
import unittest
class MyUnittest(unittest.TestCase):
def test_upper(self):
return self.assertEqual('foo'.upper(),'FOO')
if __name__ == '__main__':
unittest.main()
高階:
- 如果需要每個用例開始或者結束之前都調用一次腮鞍,用setUp()和tearDown()方法,這種用于的場景是:例如在UI自動化測試時在扰,前置是需要打開瀏覽器缕减,完成測試的操作后再把瀏覽器關閉雷客?(實際上我覺得這種場景應該是用setUpClass...)
import unittest
class MyUnittest(unittest.TestCase):
def setUp(self):
print('preparing condition')
def tearDown(self):
print('test down')
def test_upper(self):
return self.assertEqual('foo'.upper(),'FOO')
def test_lower(self):
return self.assertEqual('FOO'.lower(),'foo')
if __name__ == '__main__':
unittest.main()
但是如果想要在整個測試類進行測試之前準備或釋放環(huán)境資源芒珠,那么可以用@classmethod裝飾器在setUpClass和tearDownClass前面〗寥梗可以看這個博客的用法selenium中的setUp,tearDown與setUpClass,tearDownClass的區(qū)別及用例編寫相關注意點 這個博客也提到了皱卓,在這種場景下裹芝,需要注意的是用例之間的耦合,不要讓前一個用例的狀態(tài)影響到了下一個用例娜汁。
- skip裝飾器
包括三種嫂易,unittest.skip()、unittest.skipIf()掐禁、unittest.skipUnless()怜械,下面是官方文檔的一個例子:
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
def test_maybe_skipped(self):
if not external_resource_available():
self.skipTest("external resource not available")
# test code that depends on the external resource
pass
此外,也可以用expectedFailure()裝飾器表明這個測試預計失敗傅事。
subTest()
Reference:單元測試框架之unittest上下文管理器subTest()
當在循環(huán)中判斷時缕允,如果判斷結果不符合,我們的測試用例會直接停在當前fail的位置蹭越,使用subTest()可以讓所有的輸入都至少過一遍斷言障本。TestSuite指定測試方法的順序
Python單元測試(一)--Unittest