化測(cè)試之UnitTest詳解)
基本概念這個(gè)單元測(cè)試框架是受到了JUnit這種測(cè)試工具的啟發(fā)。它和其他編程語(yǔ)言里面那些主流的單元測(cè)試框架長(zhǎng)得很像。在風(fēng)格上, 這些框架都彼此相似。這個(gè)框架支持做自動(dòng)化測(cè)試工作。它還能夠幫助配置共享的東西。它也支持測(cè)試關(guān)機(jī)時(shí)的代碼邏輯。另外, 它能夠把很多測(cè)試樣板聚集到一起變成一個(gè)測(cè)試集。最后, 它能做到讓測(cè)試功能和報(bào)告功能分離開(kāi)來(lái), 互不相干。該結(jié)構(gòu)總共被拆解成了四個(gè)部分, 分別叫做test、test suite以及test, 具體詳情如下:測(cè)試的準(zhǔn)備工作, 指的是在測(cè)試工作開(kāi)始之前所需要進(jìn)行的所有的準(zhǔn)備行動(dòng), 以及后面所有的相關(guān)的處理和清理方面的操作。測(cè)試用例是一個(gè)獨(dú)立的測(cè)試單元, 它會(huì)針對(duì)特定的輸入數(shù)據(jù), 去檢查系統(tǒng)做出的響應(yīng)情況。這個(gè)測(cè)試套件是用來(lái)做什么的呢, 它是用來(lái)把那些需要放在一起執(zhí)行的測(cè)試用例全部收起來(lái)的。測(cè)試運(yùn)行器, 它是那種組件, 專門用來(lái)執(zhí)行各種操作, 并且還會(huì)把所有相關(guān)的測(cè)試結(jié)果輸出出來(lái)。詳解類本身為測(cè)試用例提供了有力支持。大家可以通過(guò)繼承的方式來(lái)創(chuàng)建一個(gè)全新的測(cè)試類, 然后在這個(gè)類里面設(shè)置具體的測(cè)試方法。在測(cè)試運(yùn)行時(shí), 每一個(gè)單獨(dú)的方法都會(huì)把實(shí)際得到的響應(yīng)結(jié)果和之前定好的預(yù)期結(jié)果進(jìn)行對(duì)比, 以此完成單元測(cè)試這一步驟。測(cè)試用例會(huì)包含 setUp 方法, 當(dāng)然還有 ()、() 以及 ()。需要注意, 類名稱必須以 Test作為前綴, 并且, 每一個(gè)測(cè)試用例的名稱都得以 test開(kāi)頭這樣的規(guī)矩要遵守。接下來(lái), 咱們就用一個(gè)例子來(lái)給大家展示一下具體情況。import unittestclass Test_unittest(unittest.TestCase):def setUp(self) - None:print(setup)def test(self):print(test)def tearDown(self) - None:print(teardown)if __name__ __main__:unittest.main()運(yùn)行結(jié)果里面可以看到打印了三條測(cè)試用例里的內(nèi)容, 還有 setup 方法和相應(yīng)的執(zhí)行過(guò)程, 在每次執(zhí)行測(cè)試用例的前后都會(huì)執(zhí)行這些操作, 如果增加一條測(cè)試用例的話, setup 方法也會(huì)再額外執(zhí)行一次, 如下圖所示:所以, 如果希望初始化的方法以及結(jié)束的方法各自僅僅被執(zhí)行一次的話, 是可以借助對(duì)應(yīng)的注解來(lái)實(shí)現(xiàn)的, 具體的情況是要在相關(guān)的方法的前面添加上特定的注解標(biāo)識(shí), 請(qǐng)大家詳細(xì)參考下面所提供的具體示例內(nèi)容以及最終產(chǎn)生的執(zhí)行結(jié)果。import unittestclass Test_unittest(unittest.TestCase):classmethoddef setUpClass(cls) - None:print(setup)def testcase1(self):print(testcase1)def testcase2(self):print(testcase2)def tearDown(self) - None:print(teardown)if __name__ __main__:unittest.main()從能夠觀察到如果使用了()這個(gè)方法情況的話就僅僅只會(huì)進(jìn)行一次初始化動(dòng)作, 反之如果沒(méi)有使用該方法的狀況下每條用例執(zhí)行的操作內(nèi)容都將會(huì)分別再各自去實(shí)施一次。常用方法斷言在測(cè)試用例里, 大家平時(shí)經(jīng)常用到斷言操作, 還會(huì)用到用skip來(lái)跳過(guò)某些測(cè)試用例的步驟。另外, 這個(gè)框架自身也帶有一套專門的斷言辦法, 具體來(lái)看, 主要包含下面這幾類情況。這個(gè)動(dòng)作就是表示直接跳過(guò)某個(gè)環(huán)節(jié)。在實(shí)際開(kāi)展的測(cè)試工作里面, 如果某些存在功能缺陷的具體功能點(diǎn), 它們所關(guān)聯(lián)的自動(dòng)化的測(cè)試用例根本無(wú)法成功執(zhí)行, 或者那些壓根就不會(huì)去執(zhí)行的用例場(chǎng)景, 大家是可以采用名稱為skip的那個(gè)方法來(lái)進(jìn)行處理操作的, 它這種具體的使用方式如下所示。1.跳過(guò)這個(gè)步驟的操作不需要用戶提供任何具體的理由說(shuō)明, 該操作會(huì)直接且無(wú)條件地予以執(zhí)行。2.當(dāng)判斷條件為真值的時(shí)候, 系統(tǒng)去執(zhí)行動(dòng)作, 這個(gè)邏輯表達(dá)式寫成點(diǎn)括號(hào)加二大于引號(hào)一引號(hào)逗號(hào)帶引號(hào)理由引號(hào)括號(hào)的這種格式。3.當(dāng)判斷條件的結(jié)果是假的時(shí)候, 就執(zhí)行括號(hào)里面的內(nèi)容, 也就是把大于號(hào)的右半部分和符號(hào)一起用引號(hào)括起來(lái)的那部分當(dāng)做理由, 整體來(lái)看就是“(12’理由’)”這一坨。4.在執(zhí)行過(guò)程中發(fā)生的錯(cuò)誤, 不會(huì)被計(jì)算到不通過(guò)的用例數(shù)量里面。咱們接下來(lái)看一下那個(gè)示例, 那個(gè)方法呢它是被跳過(guò)的, 原因是說(shuō)這個(gè)方法里面用到了斷言, 但是這個(gè)斷言的結(jié)果它是對(duì)不上的, 所以呢它就蹦出了報(bào)錯(cuò)的信息。import unittestclass Test_unittest(unittest.TestCase):classmethoddef setUpClass(cls) - None:print(setup)unittest.skipdef testcase1(self):print(testcase1)def testcase2(self):a 1self.assertEqual(a,2,msgerror)print(testcase2)def tearDown(self) - None:print(teardown)if __name__ __main__:unittest.main()測(cè)試套件當(dāng)一個(gè)類里面包含了多個(gè)測(cè)試用例, 并且在當(dāng)前的運(yùn)行狀態(tài)下這些測(cè)試用例并不會(huì)被同時(shí)執(zhí)行的話, 那么我們可以考慮將這些測(cè)試用例添加到一個(gè)測(cè)試套件suite中去進(jìn)行統(tǒng)一管理和運(yùn)行。需要注意的是, 這里提到的在中suite中運(yùn)行的方式, 并不是指直接在現(xiàn)有的代碼文件里進(jìn)行編寫的操作, 而是需要我們?nèi)ブ匦滦陆ㄒ粋€(gè)專門的源文件py文件來(lái)實(shí)現(xiàn)這一過(guò)程。1.把那些東西一個(gè)接著一個(gè)地, 全都加入到這個(gè)名為suite的對(duì)象里面去。第一步是導(dǎo)入該文件中的類。第二步是定義一個(gè)套件的名稱以及對(duì)應(yīng)的方法。第三步是對(duì)該套件增加測(cè)試用例。第四步是定義運(yùn)行的名稱。第五步是使用運(yùn)行方法并添加測(cè)試套件, 這樣就可以啟動(dòng)運(yùn)行了, 不過(guò)需要注意的是這個(gè)過(guò)程得把用例一個(gè)一個(gè)地去添加。2.先創(chuàng)建一個(gè)空的列表, 使用方括號(hào)將用例全部存放進(jìn)去, 接著讓程序執(zhí)行操作:3.通過(guò)直接讀取類名的這種方式來(lái)執(zhí)行操作, 它是屬于最簡(jiǎn)單的一個(gè)方法, 同時(shí)也是最為方便的一個(gè)手段, 但是在這種情況之下, 不能夠去使用單引號(hào)。4.這也是一個(gè)去讀取名字的操作步驟, 但是在這種情形之下, 大家容易遭遇找不到具體的類的情況, 所以需要在這個(gè)名稱的前面位置強(qiáng)行添加上一個(gè)文件的文件名。1.在編寫完腳本之后, 重新新建一個(gè)文件, 然后在里面把對(duì)應(yīng)的測(cè)試用例添加到套件當(dāng)中, 這樣就能實(shí)現(xiàn)全部執(zhí)行了。2.只要是在網(wǎng)絡(luò)上把那個(gè)源代碼給下載下來(lái), 然后就把它復(fù)制粘貼到那個(gè)lib目錄下面, 這樣的操作就直接可以把東西給導(dǎo)入進(jìn)去。關(guān)于這種方法的主要解析。這是那個(gè)被大家認(rèn)為實(shí)現(xiàn)起來(lái)最為簡(jiǎn)單、使用體驗(yàn)也格外便捷的HTTP功能庫(kù)的具體概述, 它總共包含了七個(gè)非常核心的操作方法。打個(gè)比方來(lái)說(shuō), 如果是進(jìn)行那種比較普通的接口測(cè)試的話, 那么這些接口彼此之間往往是不存在什么關(guān)聯(lián)性的。鑒于這種情況的存在, 用戶只需要直接地去定義相應(yīng)的變量, 進(jìn)而就可以順利發(fā)起包括get請(qǐng)求在內(nèi)的以及post請(qǐng)求這樣的操作了。其中, post請(qǐng)求常用的方式分為json格式和其他形式兩種。請(qǐng)求參數(shù)的具體樣子如截圖所示。如果需要進(jìn)行鑒權(quán), 就需要導(dǎo)入auth包, 并且將這個(gè)包放在請(qǐng)求方法的后面。方法詳解如果想了解具體的操作方法, 您可以直接按住鍵盤上的Ctrl鍵不放, 同時(shí)用鼠標(biāo)左鍵點(diǎn)擊“方法查看”這一選項(xiàng), 這樣就可以查看對(duì)應(yīng)的源碼信息了。1.請(qǐng)求地址的url, 也就是那個(gè)用來(lái)連接服務(wù)器的網(wǎng)絡(luò)位置。2.data,這個(gè)數(shù)據(jù)是字典, 或者是字節(jié)序列, 又或者是文件對(duì)象, 這些都是用來(lái)作為其傳入內(nèi)容的具體形式。3.json指的是那種叫做json格式的玩意兒呢, 它是用來(lái)作為一些東西的內(nèi)容的。4.需要提交一個(gè)字典, 并且要在字典里面加入 HTTP 定制頭的相關(guān)信息。5.將字典里的元素或者數(shù)組中的元素。6.在配置當(dāng)中, 會(huì)有一個(gè)名叫auth的地方, 它采用的是元祖這種形式, 主要是用來(lái)支持那種叫做HTTP認(rèn)證的某種功能。7.這個(gè) files, 它是一個(gè)叫做字典類型的數(shù)據(jù)結(jié)構(gòu), 專門用來(lái)進(jìn)行文件的傳輸操作。8.把超時(shí)的時(shí)長(zhǎng)給設(shè)定好, 用的單位是秒。9.這是一種字典類型, 用來(lái)設(shè)定訪問(wèn)代理服務(wù)器, 可以增加登錄認(rèn)證。10.這是一個(gè)關(guān)于布爾類型的是非判斷, 默認(rèn)情況下其值為真, 用于控制重定向功能的開(kāi)啟與關(guān)閉。11.判斷選項(xiàng)是選擇真還是選擇假, 默認(rèn)值是選擇真, 這一項(xiàng)的功能是用來(lái)控制是否在獲取到內(nèi)容之后立刻進(jìn)行下載的操作開(kāi)關(guān)狀態(tài)。12.默認(rèn)情況是True, 意思是這個(gè)選項(xiàng)會(huì)被激活。這個(gè)是關(guān)于證書開(kāi)啟的開(kāi)關(guān), 它的作用是啟用認(rèn)證功能中的SSL證書。13.cert: 本地ssl證書路徑返回方法詳解1.也就是我們通常所說(shuō)的那個(gè), 從服務(wù)器方面返回過(guò)來(lái)的, 關(guān)于http協(xié)議響應(yīng)的狀態(tài)編碼, 這個(gè)內(nèi)容。2.. #返回的是bytes型也就是二進(jìn)制的數(shù)據(jù)3.返回來(lái)的那個(gè)http請(qǐng)求頭。4..json() # 返回響應(yīng)中的Json數(shù)據(jù)5..url # 返回url6.. # 返回響應(yīng)的編碼格式7.我們來(lái)看看如何從返回的響應(yīng)里面, 找到那個(gè)你要的東西。8.這里是文本的部分, 返回的內(nèi)容是類型的數(shù)據(jù)。詳解當(dāng)遇到那些前后存在接口依賴關(guān)系的情況, 就比如需要從前面的請(qǐng)求里面獲取token, 并且把這個(gè)token作為參數(shù)用在后面的那個(gè)接口請(qǐng)求里進(jìn)行提交的時(shí)候, 使用上述的那種方法進(jìn)行試驗(yàn)的話, 顯然并不合適。如果按照上述的方法來(lái)操作的話, 就必須去定義非常多的變量, 然后還得根據(jù)依賴關(guān)系把它添加到對(duì)應(yīng)的請(qǐng)求參數(shù)之中。這種方法是通過(guò)會(huì)話的形式來(lái)進(jìn)行, 并且在整個(gè)過(guò)程中都保持貫通的狀態(tài)。因?yàn)橹恍枰砑右淮? 所以在之后的所有請(qǐng)求里面都可以直接使用到相關(guān)的內(nèi)容。解釋1.這個(gè)系統(tǒng)屬于缺陷管理系統(tǒng), 在進(jìn)行登錄操作的過(guò)程里面, 必須把響應(yīng)內(nèi)容里的特定字段提取出來(lái), 并且將其作為后續(xù)其他請(qǐng)求的必要參數(shù)攜帶過(guò)去, 如果省略了這一步驟, 就會(huì)導(dǎo)致登錄流程無(wú)法成功執(zhí)行。2.因此在整體架構(gòu)的設(shè)計(jì)層面, 是完全可以將登錄這一具體操作環(huán)節(jié)放置到setup函數(shù)內(nèi)部的, 這種做法與UI自動(dòng)化測(cè)試中的思路是保持高度一致的, 也就是說(shuō), 它類似于把登錄步驟統(tǒng)一放在初始化階段去執(zhí)行。3.我們?cè)谂渲玫倪^(guò)程中, 把從服務(wù)器那里接收到的響應(yīng)內(nèi)容的值, 全部都添加到了這個(gè)請(qǐng)求里面去, 同時(shí)在操作之中, 還特意添加了瀏覽器的UA標(biāo)識(shí)信息。4.參數(shù)是可以進(jìn)行復(fù)用的, 從頭開(kāi)始到結(jié)束這個(gè)過(guò)程中所請(qǐng)求的那些變量全部都是rsp, 而在body里面所涉及到的那些參數(shù)它們?nèi)际莇ict類型的, 這樣做起來(lái)編寫起來(lái)簡(jiǎn)單又方便。定義一個(gè)變量, 讓這個(gè)名字叫做s的變量去承接那個(gè)會(huì)話的情況, 然后后續(xù)的所有的環(huán)節(jié)當(dāng)中, 都要使用這個(gè)由s所代表的會(huì)話狀態(tài)來(lái)發(fā)起相關(guān)的網(wǎng)絡(luò)請(qǐng)求操作。定義一個(gè)變量, 讓該變量的值等于s去發(fā)起請(qǐng)求之后所得到的結(jié)果, 也就是讓rsp等于s。需要在會(huì)話請(qǐng)求的頭文件中添加這個(gè)內(nèi)容, 如果不這樣做就無(wú)法成功登錄, 需要提醒的是, 這個(gè)id是存在于響應(yīng)信息里的。由于響應(yīng)信息是以json這種字典格式來(lái)呈現(xiàn)的, 因此當(dāng)需要將該內(nèi)容添加到請(qǐng)求頭里面的時(shí)候, 就必須得去嚴(yán)格按照截圖里所展示的那種格式來(lái)進(jìn)行操作才行。如果在需要往字典中去新增字段或者添加一些具體的內(nèi)容方面的話, 那么應(yīng)該遵循那個(gè)截圖所示出來(lái)的那種特定的格式來(lái)進(jìn)行操作?!畑xx’當(dāng)把這個(gè)等于“xxx”的鍵值對(duì)進(jìn)行設(shè)置的時(shí)候, 如果在那個(gè)字典里面存在這個(gè)鍵和值的配對(duì)的話, 那么這個(gè)現(xiàn)有的值就會(huì)直接被刷新成為新的內(nèi)容相反地, 假如那個(gè)字典里完全沒(méi)有這一組鍵和對(duì)應(yīng)的值搭配的話, 那么系統(tǒng)就會(huì)執(zhí)行追加的操作, 把這一組全新的鍵和值作為新的條目添加進(jìn)那個(gè)字典的里面去。進(jìn)行接口的實(shí)際測(cè)試操作時(shí), 需要把那個(gè)token添加到那些文件的標(biāo)題部分里面去。在我們公司做實(shí)際項(xiàng)目的時(shí)候, 去調(diào)接口之前, 得先弄到一個(gè)token。你得先去請(qǐng)求那個(gè)用來(lái)獲取token的東西, 等拿到了token這個(gè)數(shù)字或者字符串之后, 把它放到頭文件里面, 這樣在后面調(diào)接口的用的時(shí)候就能用了。self的后面接上小括號(hào), 小括號(hào)里面是雙大括號(hào)括起來(lái)的字符串內(nèi)容, 字符串內(nèi)容是token冒號(hào)rsp的點(diǎn)方法調(diào)用json?!甦ata’‘token’})您可以向左側(cè)或者右側(cè)拖動(dòng), 以此來(lái)查看完整的全部代碼部分。通過(guò)在setup初始化方法中去調(diào)用獲取token這個(gè)操作, 然后就能把拿到的token值拿到手, 接著把這個(gè)得到的數(shù)據(jù)整體添加到頭信息里面去, 這樣的話在后續(xù)的其他請(qǐng)求過(guò)程中也都不需要再進(jìn)行額外的頭部添加操作了。使用ddt做參數(shù)化關(guān)于DDT數(shù)據(jù)驅(qū)動(dòng)測(cè)試這一事宜, 首要的任務(wù)在于執(zhí)行pip list ddt這一些操作以便于安裝那個(gè)被稱為第三方的庫(kù), 接著我們需要確保在代碼文本的最頂端位置處, 導(dǎo)入在該庫(kù)內(nèi)部所存在的名為data的部分。從ddt導(dǎo)入ddt、data以及相關(guān)的函數(shù)和類, 在測(cè)試類的前面聲明使用ddt, 通過(guò)ddt注解來(lái)實(shí)現(xiàn)。1、在編寫測(cè)試用例之前, 需要先進(jìn)行聲明動(dòng)作, 具體的方式就是使用關(guān)鍵字“data”。data(test1,test2)def test_ddt1(self,value):print(value)在這里插入代碼片左右滑動(dòng)查看完整代碼在運(yùn)行的結(jié)果里面, 這個(gè)用例被執(zhí)行了兩次。第一次輸出的內(nèi)容是test1, 第二次輸出的內(nèi)容是test2。2、在數(shù)據(jù)的應(yīng)用方法里面, 進(jìn)行文件的讀取操作。這個(gè)辦法是需要執(zhí)行解包操作的, 因此務(wù)必要借助于某個(gè)特定的方法, 而要在測(cè)試用例開(kāi)始之前進(jìn)行聲明, 操作的時(shí)候需要在前面加上一個(gè)符號(hào)。def readline(self):date []file open(D:\\base64\\keyid.txt,r,encodingutf-8)for line in file:date.append(line.split())return datedata(*readline())unpackdef test_ddt2(self,vars):print(vars)我們對(duì)運(yùn)行的結(jié)果進(jìn)行解釋, 首先定義一個(gè)用于讀取文件的方法, 然后定義一個(gè)列表數(shù)組, 接下來(lái)使用文件的開(kāi)放方法去讀取那個(gè)名為“txt1”的文件, 讀取的模式設(shè)定為讀的形式, 編碼的格式被確定成utf-8, 通過(guò)運(yùn)用for循環(huán)這種方式來(lái)不停地、持續(xù)地讀取文件里的每一行內(nèi)容, 在此過(guò)程里, 以換行符即\n作為每一行的結(jié)尾標(biāo)志, 并以逗號(hào)用來(lái)分隔開(kāi)里面的每一個(gè)參數(shù), 在最終完成這些步驟后, 返回data這個(gè)值, 目的是為了讓下面的部分可以直接拿去調(diào)用。在上面寫了讀取方法之后 , 在測(cè)試用例前 , 直接使用該方法即可 , data*這種形式接著使用解包的方法即可。生成測(cè)試報(bào)告按照上述的方法, 先把測(cè)試用例編寫好了, 然后再結(jié)合那個(gè)能夠生成報(bào)告的框架來(lái)去生成接口測(cè)試報(bào)告。你可以到網(wǎng)上去找那個(gè)庫(kù)里邊的文件, 然后下載下來(lái), 接著把它放到你已經(jīng)安裝好的目錄之中, 具體來(lái)說(shuō)就是放到lib這個(gè)文件夾里面去, 這樣做完之后你以后就可以直接來(lái)使用它了。最后, 作為一名已經(jīng)經(jīng)歷過(guò)這些的人, 真心希望大家能少踩一些坑, 不要走太多彎路。如果你實(shí)在不想再重新體驗(yàn)?zāi)欠N在學(xué)習(xí)過(guò)程里找不到靠譜資料, 結(jié)果堅(jiān)持沒(méi)幾天干脆就半途而廢的糟糕感覺(jué), 那么我在這里把自己手里的一些關(guān)于軟件測(cè)試的學(xué)習(xí)資源拿出來(lái)分享給你。這些東西, 對(duì)于那些想要學(xué)習(xí)【軟件測(cè)試】的朋友來(lái)說(shuō), 基本上應(yīng)該算是比較全面、也比較完整的備戰(zhàn)素材庫(kù)了, 希望能在你前行的路上稍微幫你一把。如果你覺(jué)得這些東西你能用得上, 可以直接拿去使用就行:這些資料, 對(duì)于軟件測(cè)試的朋友來(lái)說(shuō)應(yīng)該是最全面最完整的備戰(zhàn)倉(cāng)庫(kù)。這個(gè)倉(cāng)庫(kù)也陪伴上萬(wàn)個(gè)測(cè)試工程師們走過(guò)最艱難的路程。希望也能幫助到你