基于Python的接口自動(dòng)化unittest測(cè)試框架和ddt數(shù)據(jù)驅(qū)動(dòng)詳解
引言
在編寫接口自動(dòng)化用例時(shí),我們一般針對(duì)一個(gè)接口建立一個(gè).py文件,一條接口測(cè)試用例封裝為一個(gè)函數(shù)(方法),但是在批量執(zhí)行的過(guò)程中,如果其中一條出錯(cuò),后面的用例就無(wú)法執(zhí)行,還有在運(yùn)行大量的接口測(cè)試用例時(shí)測(cè)試數(shù)據(jù)如何管理和加載。針對(duì)測(cè)試用例加載以及執(zhí)行控制,python語(yǔ)言提供了unittest單元測(cè)試框架,將測(cè)試用例編寫在unittest框架下,使用該框架可以單個(gè)或者批量加載互不影響的用例執(zhí)行及更靈活的執(zhí)行控制,對(duì)于更好的進(jìn)行測(cè)試數(shù)據(jù)的管理和加載,這里我們引入數(shù)據(jù)驅(qū)動(dòng)的模塊:ddt,測(cè)試數(shù)據(jù)和測(cè)試腳本的分離,通過(guò)ddt數(shù)據(jù)驅(qū)動(dòng)來(lái)加載測(cè)試數(shù)據(jù)到測(cè)試用例腳本中,通常在接口自動(dòng)化測(cè)試中會(huì)將unittest和ddt結(jié)合起來(lái)使用,從而實(shí)現(xiàn)測(cè)試用例腳本和測(cè)試數(shù)據(jù)的載入來(lái)完成測(cè)試的執(zhí)行。下面來(lái)看看unittest框架和ddt這兩個(gè)模塊具體的應(yīng)用。
一、unittest測(cè)試框架
unittest單元測(cè)試框架是python語(yǔ)言的一套標(biāo)準(zhǔn)模塊,封裝提供了諸多操作測(cè)試用例和用例加載、測(cè)試前置和場(chǎng)景恢復(fù)以及測(cè)試結(jié)果輸出等一系列類和方法。
1.unittest框架中最核心四個(gè)組件概念:
(1)TestCase:測(cè)試用例類,編寫測(cè)試用例腳本時(shí)需要繼承該類,從而具有該類的屬性和方法,一個(gè)TestCase實(shí)例就是一個(gè)測(cè)試用例,其中測(cè)試用例方法都以test開(kāi)頭。
(2)TestSuite:測(cè)試集,也就是測(cè)試用例的集合,用來(lái)組織用例。
(3)testrunner:用來(lái)執(zhí)行測(cè)試用例,并返回測(cè)試用例的執(zhí)行結(jié)果,可以用圖形或者文本將測(cè)試結(jié)果形象地展現(xiàn)出來(lái),HTMLTestRunner用來(lái)生成圖形化的報(bào)告,TextTestRunner用來(lái)生成簡(jiǎn)單的文本測(cè)試結(jié)果。
(4)testfixure:測(cè)試夾件,主要用于測(cè)試用例的前置初始化和執(zhí)行后的銷毀。
2.testcase----測(cè)試用例
- 新建一個(gè)的.py測(cè)試用例文件必須是test開(kāi)頭,如test_login.py,主要后續(xù)用于識(shí)別測(cè)試用例文件編寫測(cè)試用例的類,必須繼承unittest.TestCase,做為測(cè)試類
- 測(cè)試類中用例的方法名稱必須以test開(kāi)頭,用于識(shí)別測(cè)試用例數(shù)
- 測(cè)試類中的用例執(zhí)行順序,按照以test開(kāi)頭的方法后的Ascill碼順序執(zhí)行(0~9,A~Z,a~z)
3.testfixure----測(cè)試夾件
- 也叫測(cè)試夾具,主要是用例前置的初始化以及執(zhí)行后的銷毀
- 測(cè)試夾件提供兩種方法,一種是類級(jí)別的:setup()和teardown(),一種是方法級(jí)別的:setUpClass()和tearDownClass()
- 類級(jí)別的測(cè)試夾件,每一條測(cè)試用例執(zhí)行之前與之后都要運(yùn)行一次setup()和teardown();方法級(jí)別的測(cè)試夾件,所有測(cè)試用例執(zhí)行之前到執(zhí)行完成只運(yùn)行一次setUpClass()和tearDownClass()
下面通過(guò)簡(jiǎn)單的代碼示例看看TestCase與TestFixure的使用
(1)使用setup()和teardown(),創(chuàng)建test_666.py文件編輯如下代碼:
import unittest class test_unittest(unittest.TestCase): def setUp(self): print("測(cè)試環(huán)境初始化,開(kāi)始執(zhí)行setup") def tearDown(self): print("測(cè)試執(zhí)行完成,運(yùn)行teardown") print("------------------------------") def test_a(self): print("開(kāi)始執(zhí)行test_a用例") def test_A(self): print("開(kāi)始執(zhí)行test_A用例") def test_1(self): print("開(kāi)始執(zhí)行test_1用例") def notest_1(self): print("不執(zhí)行notest_1用例") if __name__ == "__main__": unittest.main()
執(zhí)行后,輸出如下:
在代碼中我們編寫了4個(gè)def用例方法,只執(zhí)行了3個(gè)def,因?yàn)樽詈笠粋€(gè)def不是test開(kāi)頭??梢钥吹矫繄?zhí)行一個(gè)def用例,setup()和teardown()都會(huì)執(zhí)行一次,其中按照?qǐng)?zhí)行順序:test_1最先執(zhí)行,test_A其后,test_a最后執(zhí)行
(2)使用setUpClass()和tearDownClass()
對(duì)于setUpClass()和tearDownClass()我們只需將上面代碼,稍微修改即可
import unittest class test_unittest(unittest.TestCase): @classmethod def setUpClass(cls): print("測(cè)試環(huán)境初始化,開(kāi)始執(zhí)行setup") @classmethod def tearDownClass(cls): print("測(cè)試執(zhí)行完成,運(yùn)行teardown") print("------------------------------") def test_a(self): print("開(kāi)始執(zhí)行test_a用例") def test_A(self): print("開(kāi)始執(zhí)行test_A用例") def test_1(self): print("開(kāi)始執(zhí)行test_1用例") if __name__ == "__main__": unittest.main()
運(yùn)行效果如下:
可以看到所有用例都執(zhí)行完后,setUpClass()和tearDownClass()只運(yùn)行了一次。因此在編寫一個(gè)測(cè)試腳本時(shí),里面寫了多個(gè)測(cè)試用例,
這時(shí)我們希望的是所有用例執(zhí)行完成后再銷毀環(huán)境,這時(shí)使用setUpClass()
和tearDownClass()
就比較好了。
3.TestSuite----測(cè)試集
unittest框架下提供了unittest.TestSuite()和unittest.TestLoader()類,這兩個(gè)類下封裝了加載用例的方法,用于加載測(cè)試用例到測(cè)試集中
(1)unittest.TestSuite()提供單個(gè)用例加載方法
addTest():?jiǎn)蝹€(gè)用例加載,當(dāng)然也可以將多個(gè)用例的方法名放入列表中添加到addTest()中,加載多條測(cè)試用例
(2)unittest.TestLoader()提供批量加載或發(fā)現(xiàn)用例的方法
loadTestsFromTestCase(測(cè)試類名):添加一個(gè)測(cè)試類
loadTestsFromModule(模塊名):添加一個(gè)模塊
discover(測(cè)試用例的所在目錄):指定目錄去加載,會(huì)自動(dòng)尋找這個(gè)目錄下所有符合命名規(guī)則的測(cè)試用例
4.testrunner----測(cè)試運(yùn)行
testrunner就是用來(lái)執(zhí)行測(cè)試用例的,并且可以生成相應(yīng)的測(cè)試報(bào)告。測(cè)試報(bào)告有兩種展示形式,一種是text文本,一種是html格式。
html格式的就是HTMLTestRunner了,HTMLTestRunner是Python標(biāo)準(zhǔn)庫(kù)的unittest框架的一個(gè)擴(kuò)展,它可以生成一個(gè)直觀清晰的HTML測(cè)試報(bào)告。使用的前提就是要下載HTMLTestRunner.py,下載完后放在python的安裝目錄下的scripts目錄下即可。
通過(guò)代碼示例看看testsuite和testrunner這兩個(gè)組件的使用,上面的test_666.py用例文件我們已經(jīng)寫好了3條用例了,現(xiàn)在我們來(lái)加載這些用例
新建run_case.py文件,該文件和test_666.py文件放置在同一個(gè)包文件:test下,run_case.py文件編輯如下代碼運(yùn)行:
import unittest from test.test_666 import test_unittest # 單個(gè)用例加載 suite = unittest.TestSuite() case1 = test_unittest('test_1') case2 = test_unittest('test_a') suite.addTest(case1) suite.addTest(case2) print(suite) print("------------------") # 批量用例加載 case_path = r"E:\api_test\test" # 按文件路徑加載,注意該文件為包文件即文件下有__init__.py all_case = unittest.defaultTestLoader.discover(case_path,pattern="test_666*.py",top_level_dir=None) all_case1 = unittest.defaultTestLoader.loadTestsFromTestCase(test_unittest) # 按類名稱加載 print(all_case) print("------------------") print(all_case1)
輸出結(jié)果如下:
E:\api_test\Scripts\python.exe E:/api_test/test_bak/run_case.py
<unittest.suite.TestSuite tests=[<test.test_666.test_unittest testMethod=test_1>, <test.test_666.test_unittest testMethod=test_a>]>
------------------
<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<unittest.suite.TestSuite tests=[<test_666.test_unittest testMethod=test_1>, <test_666.test_unittest testMethod=test_A>, <test_666.test_unittest testMethod=test_a>]>]>]>
------------------
<unittest.suite.TestSuite tests=[<test.test_666.test_unittest testMethod=test_1>, <test.test_666.test_unittest testMethod=test_A>, <test.test_666.test_unittest testMethod=test_a>]>
Process finished with exit code 0
通過(guò)unittest框架下提供的加載用例的諸多方法,我們就可以單個(gè)或者批量加載用例,后續(xù)可以將加載的用例集引入到HTMLTestRunner.py模塊生成可視化的測(cè)試報(bào)告
5.assert----測(cè)試斷言
無(wú)論是什么樣的測(cè)試用例,最后都需要有用例執(zhí)行后的驗(yàn)證,在接口自動(dòng)化測(cè)試中我們執(zhí)行完接口用例也需要驗(yàn)證斷言用例執(zhí)行是否滿足我們的預(yù)期。unittest提供了豐富的斷言方法,常見(jiàn)的斷言如下表:
二、ddt數(shù)據(jù)驅(qū)動(dòng)
- @ddt:類的裝飾器,繼承的是TestCase類
- @data():@data裝飾符可以把參數(shù)當(dāng)成測(cè)試數(shù)據(jù),參數(shù)可以是單個(gè)值、列表、元祖、字典這些類型,用于輸入測(cè)試數(shù)據(jù)
- @unpack:分解數(shù)據(jù)標(biāo)志,主要是把元祖和列表解析成多個(gè)參數(shù)
- @file_data():輸入文件,如json或者yaml類型文件
(1)輸入簡(jiǎn)單的參數(shù):?jiǎn)蝹€(gè)值、列表、元祖、字典
import unittest from ddt import data,unpack,ddt @ddt class myddt(unittest.TestCase): @data("123") # 單個(gè)值 def test1(self,testdata1): print(testdata1) print("------------------") @data([1,2,3],[4,5,6]) # 列表 def test2(self,testdata2): print(testdata2) print("------------------") """ @data((1, 2, 3)) # 元組 def test2(self, testdata3): print(testdata3) print("------------------") @data({'zhangshan':1,'wangwu':2,'lisi':3}) # 字典 def test2(self, testdata4): print(testdata4) print("------------------") """ if __name__ == '__main__': unittest.main()
?。?)使用@unpack對(duì)復(fù)雜數(shù)據(jù)結(jié)構(gòu),如元組、列表數(shù)據(jù)進(jìn)行分解
代碼示例:
import unittest from ddt import data,unpack,ddt @ddt class myddt(unittest.TestCase): @data([1,2],[3,4]) # 列表 @unpack def test2(self, testdata1,testdata2): print("拆解的第一個(gè)參數(shù):",testdata1) print("拆解的第二個(gè)參數(shù):", testdata2) print("------------------") if __name__ == '__main__': unittest.main()
運(yùn)行后輸出如下:
(3)使用@file_data()輸入文件格式測(cè)試數(shù)據(jù)
編輯一個(gè)data.json的文件,代碼示例:
import unittest from ddt import file_data,ddt @ddt class myddt(unittest.TestCase): @file_data(r"E:\api_test\test\data.json") def test1(self, *value): print(value) if __name__ == '__main__': unittest.main()
通過(guò)ddt和unittest框架的結(jié)合就可以實(shí)現(xiàn)測(cè)試用例腳本編寫、測(cè)試執(zhí)行控制以及測(cè)試數(shù)據(jù)的批量加載,從而完成不同接口測(cè)試用例的批量執(zhí)行和覆蓋測(cè)試不同測(cè)試場(chǎng)景。
到此這篇關(guān)于基于Python的接口自動(dòng)化unittest測(cè)試框架和ddt數(shù)據(jù)驅(qū)動(dòng)詳解的文章就介紹到這了,更多相關(guān)Python的接口自動(dòng)化ddt數(shù)據(jù)驅(qū)動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python Unittest ddt數(shù)據(jù)驅(qū)動(dòng)的實(shí)現(xiàn)
- python 基于DDT實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)測(cè)試
- Python+unittest+DDT實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)測(cè)試
- python自動(dòng)化測(cè)試之DDT數(shù)據(jù)驅(qū)動(dòng)的實(shí)現(xiàn)代碼
- python ddt數(shù)據(jù)驅(qū)動(dòng)最簡(jiǎn)實(shí)例代碼
- python ddt實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)
- python中DDT數(shù)據(jù)驅(qū)動(dòng)的實(shí)現(xiàn)
相關(guān)文章
python 實(shí)現(xiàn)簡(jiǎn)單的FTP程序
這篇文章主要介紹了python 實(shí)現(xiàn)簡(jiǎn)單的FTP程序,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12Python3 獲取文件屬性的方式(時(shí)間、大小等)
這篇文章主要介紹了Python3 獲取文件屬性的方式(時(shí)間、大小等),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03Python常駐任務(wù)實(shí)現(xiàn)接收外界參數(shù)代碼解析
這篇文章主要介紹了Python常駐任務(wù)實(shí)現(xiàn)接收外界參數(shù)代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07Python實(shí)現(xiàn)在線批量美顏功能過(guò)程解析
這篇文章主要介紹了Python實(shí)現(xiàn)在線批量美顏功能過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06