Python接口自動化淺析unittest單元測試原理
在上一篇Python接口自動化測試系列文章:Python接口自動化淺析requests請求封裝原理,主要通過源碼分析,總結(jié)出一套簡潔的請求類封裝。
以下主要介紹unittest特性、運行流程及實際案例。
一、單元測試三連問
1、什么是單元測試?
按照階段來分,一般就是單元測試,集成測試,系統(tǒng)測試,驗收測試。
單元測試是對單個模塊、單個類或者單個函數(shù)進行測試。
將訪問接口的過程封裝在函數(shù)里面;
接口測試就變成了單元測試;
單元測試就是通過傳參,對某個模塊、某個類、某個函數(shù)進行結(jié)果輸出后驗證的測試。
2、為什么要做單元測試?
1.單元測試之后,才是集成測試,單個的功能模塊測試通過之后,才能把單個功能模塊集成起來做集成測試,為了從底層發(fā)現(xiàn)bug,減少合成后出現(xiàn)的問題。
2.越早發(fā)現(xiàn)bug越好,否則問題累計到后期,如果做錯了就要推倒重來,對于時間和人力成本來說非常耗費精力。
對于我們測試來說:單元測試是為了執(zhí)行測試用例。
3、怎么做單元測試?
Python里有兩個單元測試類:
1.Unittest(Python自帶);
2.Pytest(下載安裝);
前者多用于接口自動化項目用,后者多用于WEB自動化項目、APP自動化項目。
二、unittest模塊說明
1、unittest簡介
unittest是Python自帶的單元測試框,具備編寫用例、組織用例、執(zhí)行用例、輸出報告等自動化框架的條件,可以用來作自動化測試框架的用例組織執(zhí)行框架。
unittest框架的特性:
- 提供用例組織與執(zhí)行:當測試用例只有幾條的時候可以不考慮用例的組織,但是當測試用例數(shù)量較多時,此時就需要考慮用例的規(guī)范與組織問題。unittest單元測試框架就是用來解決這個問題的。
- 提供豐富的斷言方法:既然是測試,就有一個預期結(jié)果和實際結(jié)果的比較問題。比較就是通過斷言來實現(xiàn),unittest單元測試框架提供了豐富的斷言方法,通過捕獲返回值,并且與預期值進行比較,從而得出測試通過與否。
- 提供豐富的日志:每一個失敗用例我們都希望知道失敗的原因,所有用例執(zhí)行結(jié)束我們有希望知道整體執(zhí)行情況,比如總體執(zhí)行時間,失敗用例數(shù),成功用例數(shù)。unittest單元測試框架為我們提供了這些數(shù)據(jù)。
2、unittest組成
unittest單元測試中最核心的四個部分是:
TestCase
(測試用例)
TestSuite
(測試套件)
TestRunner
(測試運行器)
TestFixture
(測試環(huán)境數(shù)據(jù)準備和清理)
1.TestCase(測試用例):
一個TestCase的實例就是一個測試用例。什么是測試用例呢?就是一個完整的測試流程。包括測試前準備環(huán)境的搭建(setUp)、實現(xiàn)測試過程的代碼(run),以及測試后環(huán)境的還原(tearDown)。
單元測試(Unittest)的本質(zhì)也就在這里,一個測試用例就是一個完整的測試單元,通過運行這個測試單元,可以對某一個功能進行驗證。
2.TestSuite(測試套件):
一個功能的驗證往往需要多個測試用例,可以把多個測試用例集合在一起執(zhí)行,這就產(chǎn)生了測試套件TestSuite的概念。TestSuite用來組裝單個測試用例。可以通過addTest加載TestCase到TestSuite中,從而返回一個TestSuite實例。
而且TestSuite也可以嵌套TestSuite。
3.TestLoader(測試用例加載器):
用來加載TestCase到TestSuite中的,其中l(wèi)oadTestsFrom__()方法用于尋找TestCase,并創(chuàng)建它們的實例,然后添加到TestSuite中,返回TestSuite實例;
4.TextTestRunner(執(zhí)行測試用例):
用來執(zhí)行測試用例,其中run(test)會執(zhí)行TestSuite/TestCase中的run(result)方法,并將測試結(jié)果保存到TextTestResult實例中,包括運行了多少測試用例,成功多少,失敗多少等信息;
5.Test Fixture(測試環(huán)境數(shù)據(jù)準備和清理):
一個測試用例的初始化準備及環(huán)境還原,主要是setUp() 和 tearDown()方法;
比如說在測試用例中需要訪問數(shù)據(jù)庫,那么可以在setUp()中建立數(shù)據(jù)庫連接以及進行一些初始化,
在tearDown()中清除在數(shù)據(jù)庫中產(chǎn)生的數(shù)據(jù),然后關(guān)閉連接。
注意tearDown的過程很重要,要為以后的TestCase留下一個干凈的環(huán)境。
3、unittest核心工作原理
unittest的靜態(tài)類圖:
大體流程:編寫TestCase,由TestLoader加載TestCase到TestSuite,然后由TextTestRunner來運行TestSuite,最后將運行的結(jié)果保存在TextTestResult中。
三、unittest單元測試
1、實現(xiàn)思路
1.導入unittest模塊、 被測文件或者其中的類;
2.創(chuàng)建一個測試類,并繼承unittest.TestCase方法;
3.重寫setUp和tearDown方法(如果有初始化條件和結(jié)束條件)。若setup()成功運行,無論測試方法是否成功,都會運行tearDown ();
4.定義測試函數(shù),函數(shù)名以test_開頭,以識別測試用例;
5.調(diào)用unittest.main()方法運行測試用例;
6.用例執(zhí)行后,需要判斷用例是Pass還是Fail,可以用unittest.TestCase模塊的:斷言
斷言就是比對預期結(jié)果。如果不加斷言,沒有結(jié)果對比,需要手動去檢查運行的結(jié)果是否符合預期。
2、使用介紹
1.要想使用unittest單元測試框架,必須得先導入:import unittest
2.查看unittest源碼;
import unittest print(help(unittest))
從打印結(jié)果中提取出unittest簡易的例子:
import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): # test method names begin with 'test' self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main()
四、unittest實例
1、TestCase(測試用例)
看了官方代碼后,我們自己寫個例子熟悉下,并總結(jié)出規(guī)律:
import unittest class TestDemo(unittest.TestCase): # test_sub用例 def test_sub(self): self.assertEqual(2-1,1) # test_add用例 def test_add(self): self.assertEqual(2+1,3) if __name__ == "__main__": # unittest.main()是運行主函數(shù) unittest.main(verbosity=2)
運行結(jié)果為:
test_add (__main__.TestDemo) ... ok
test_sub (__main__.TestDemo) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
接下來,我們來總結(jié)一些規(guī)律:
- 使用unittest前,需導入unittest框架。
- TestDemo這個類必須繼承unittest.TestCase,TestCase類,所有測試用例類繼承的基類。
- 類內(nèi)的方法必須以test開頭,比如test_add。
- 斷言:assertEqual用來斷言預期結(jié)果和實際結(jié)果是否一致。當然unittest還包含很多其他斷言方法,后面統(tǒng)一介紹。
- 用例執(zhí)行順序。在代碼中test_sub方法寫在test_add前,但實際,test_add比test_sub先運行。為什么呢?unittest執(zhí)行測試用例,默認是根據(jù)ASCII碼的順序加載測試用例,數(shù)字與字母的順序為:0-9,A-Z,a-z。
- verbosity是一個選項,表示測試結(jié)果的信息復雜度,有0、1、2 三個值。verbosity=0 : 你只能獲得測試用例數(shù)總的結(jié)果;verbosity=1 (默認模式): 在每個成功的用例前面有個“.” 每個失敗的用例前面有個 “F”;verbosity=2 (詳細模式):測試結(jié)果會顯示每個測試用例的所有相關(guān)的信息。
如下,在測試用例中寫入斷言:
import unittest #測試MathMethod類 class TestMathMethod(unittest.TestCase): #編寫測試用例 def test_add_two_positive(self): #測試兩個正數(shù)相加 res=MathMethod(1,1).add() print("1+1的結(jié)果是:",res) self.assertEqual(2,res,"兩個正數(shù)相加出錯!") #斷言 def test_add_two_zero(self): #測試兩個0相加 res = MathMethod(0, 0).add() print("0+0的結(jié)果是:", res) self.assertEqual(0, res, "兩個0相加出錯!") #斷言 def test_add_two_negative(self): #測試兩個負數(shù)相加 res = MathMethod(-1, -1).add() print("-1+(-1)的結(jié)果是:", res) self.assertEqual(-2, res, "兩個負數(shù)相加出錯!") #斷言 if __name__ == '__main__': unittest.main()
測試用例里面的setUp函數(shù)與tearDown函數(shù)的使用:
class TestMathMethod(unittest.TestCase): def setUp(self): print("開始準備執(zhí)行測試用例!") def tearDown(self): print("結(jié)束!") #編寫測試用例 def test_add_two_positive(self): #測試兩個正數(shù)相加 res=MathMethod(1,1).add() print("1+1的結(jié)果是:",res)
setUp函數(shù):初始化環(huán)境(執(zhí)行每條用例之前,都要執(zhí)行setUp函數(shù)下面的代碼,每次都要執(zhí)行);
tearDown函數(shù):清洗環(huán)境(執(zhí)行每條用例之后,都要執(zhí)行tearDown函數(shù)下面的代碼,每次都要執(zhí)行);
setUp()、tearDown()是TestCase里的方法,寫在測試類中,就是方法的重寫。
執(zhí)行順序是:setUp->testA->tearDown->setUp->testB>tearDown
2、TestSuit(測試集)
當測試用例全部寫完,但是只想執(zhí)行其中部分,可以使用TestSuit()來收集測試用例。
import unittest from xxx import xxx#測試用例的類 suite=unittest.TestSuit() suite.addTest(測試用例的類("用例名稱1")) #用例名稱用字符串的形式傳入 suite.addTest(測試用例的類("用例名稱2")) suite.addTest(測試用例的類("用例名稱3")) .....
3、TestLoader(加載測試用例)
方式一:通過測試類來加載用例(loadTestsFromTestCase)
一次性加載測試用例類名1下的所有用例。
import unittest from xxx import xxx#測試用例的類 suite=unittest.TestSuit() loader=unittest.TestLoader() suite.addTest(loader.loadTestsFromTestCase(測試用例類名1)) #測試用例類名直接傳入
方式二:通過測試類所在的模塊加載用例(loadTestsFromModule)
一次性加載測試用例模塊名下的所有用例。
import unittest from xxx import xxx#測試用例模塊 suite=unittest.TestSuit() loader=unittest.TestLoader() suite.addTest(loader.loadTestsFromTestCase(測試用例模塊名))#測試用例模塊名直接傳入
4、生成測試報告
方式一:使用unittest自帶的TextTestRunner生成測試報告(文本格式,不推薦使用)。
TextTestRunner是一個以文本形式展示測試結(jié)果的測試運行程序類
stream 輸出報告的路徑,默認輸出控制臺;
verbosity 控制輸出報告的詳細程度,從0-2,越來越詳細;
方式二:使用第三方模塊HTMLTestRunnerNew(生成HTML格式的測試報告,推薦使用)。
file:
文件
verbosity:
詳細程度
title:
標題
description:
描述
tester:
作者
with open("接口測試報告.html","wb") as file: runner = HTMLTestRunnerNew.HTMLTestRunner(stream=file, verbosity=2, title="接口自動化測試報告", description="接口測試V1", tester="ITester軟件測試小棧") runner.run(suite)
方式三:使用unittest.defaultTestLoader.discover() 模糊匹配。
import unittest import HTMLTestRunnerNew all_testcases=unittest.defaultTestLoader.discover(contants.testcases_dir, pattern='test_*.py',top_level_dir=None) #利用上下文管理器自動關(guān)閉資源 with open(contants.reports_html,"wb+") as file: #選擇絕對路徑,把文件打開,寫進內(nèi)容 (報告的文件名直接寫在路徑里面) runner=HTMLTestRunnerNew.HTMLTestRunner(stream=file, title="接口自動化測試報告", description="接口測試V1", tester="ITester軟件測試小棧") runner.run(all_testcases)
到此這篇關(guān)于Python接口自動化淺析unittest單元測試原理的文章就介紹到這了,更多相關(guān)Python接口自動化unittest單元測試內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!
版權(quán)聲明:本站文章來源標注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學習參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。