Python unittest裝飾器實(shí)現(xiàn)原理及代碼
1、前言
前面講到unittest里面setUp可以在每次執(zhí)行用例前執(zhí)行,這樣有效的減少了代碼量,但是有個(gè)弊端,比如打開(kāi)瀏覽器操作,每次執(zhí)行用例時(shí)候都會(huì)重新打開(kāi),這樣就會(huì)浪費(fèi)很多時(shí)間。
于是就想是不是可以只打開(kāi)一次瀏覽器,執(zhí)行完用例再關(guān)閉呢?這就需要用到裝飾器(@classmethod)來(lái)解決了。
2、@classmethod 裝飾器中的 setUpClass() 和 tearDownClass() 與 setUp() 和 tearDown() 的區(qū)別
- setUp():每個(gè)測(cè)試 case 運(yùn)行之前運(yùn)行
- tearDown():每個(gè)測(cè)試 case 運(yùn)行完之后執(zhí)行
- setUpClass():必須使用 @classmethod 裝飾器, 所有 case 運(yùn)行之前只運(yùn)行一次
- @是修飾符,classmethod 是 python 里的類方法
- tearDownClass():必須使用 @classmethod 裝飾器, 所有 case 運(yùn)行完之后只運(yùn)行一次
import unittest
class Test(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print("-----開(kāi)始執(zhí)行用例-----")
def setUp(self) -> None:
print("執(zhí)行用例準(zhǔn)備動(dòng)作...")
def test01(self):
print("第一條用例正在執(zhí)行...")
def test02(self):
print("第二條用例正在執(zhí)行...")
def tearDown(self) -> None:
print("用例執(zhí)行完結(jié)動(dòng)作...")
@classmethod
def tearDownClass(cls) -> None:
print("-----用例執(zhí)行結(jié)束-----")
if __name__ == '__main__':
unittest.main()
#執(zhí)行結(jié)果如下:
"""
-----開(kāi)始執(zhí)行用例-----
執(zhí)行用例準(zhǔn)備動(dòng)作...
第一條用例正在執(zhí)行...
用例執(zhí)行完結(jié)動(dòng)作...
執(zhí)行用例準(zhǔn)備動(dòng)作...
第二條用例正在執(zhí)行...
用例執(zhí)行完結(jié)動(dòng)作...
-----用例執(zhí)行結(jié)束-----
"""
from selenium import webdriver
import unittest
from time import sleep
class DymLogin(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
"""
所有的用例只需要執(zhí)行一次打開(kāi)瀏覽器操作
"""
print("Test start...")
cls.dr = webdriver.Chrome()
cls.dr.get("http://www.duoyoumi.com/")
cls.dr.implicitly_wait(10)
cls.dr.maximize_window()
cls.dr.find_element_by_class_name("login").click()
sleep(1)
@classmethod
def tearDownClass(cls) -> None:
sleep(2)
cls.dr.quit()
print("Test end...")
def test_login01(self):
"""
賬號(hào)密碼都為空
"""
self.dr.find_element_by_name("loginName").clear()
self.dr.find_element_by_name("loginPwd").clear()
self.dr.find_element_by_xpath('//*[@id="loginForm"]/div/div/div/div[2]/div[1]/div[2]').click() #登錄操作
TipsMsg = self.dr.find_element_by_class_name("promptLogin").text
self.assertEqual(TipsMsg,"-請(qǐng)輸入登錄賬號(hào)!",msg="Test_login01 login exception")
def test_login02(self):
"""
賬號(hào)正確,密碼為空
"""
self.dr.find_element_by_name("loginName").clear()
self.dr.find_element_by_name("loginPwd").clear()
self.dr.find_element_by_name("loginName").send_keys("17779828887")
self.dr.find_element_by_xpath('//*[@id="loginForm"]/div/div/div/div[2]/div[1]/div[2]').click() # 登錄操作
TipsMsg = self.dr.find_element_by_class_name("promptLogin").text
self.assertEqual(TipsMsg, "-請(qǐng)輸入密碼!", msg="Test_login02 login exception")
def test_login03(self):
"""
賬號(hào)密碼都正確
"""
self.dr.find_element_by_name("loginName").clear()
self.dr.find_element_by_name("loginPwd").clear()
self.dr.find_element_by_name("loginName").send_keys("17779828887")
self.dr.find_element_by_name("loginPwd").send_keys("zy295240???")
self.dr.find_element_by_xpath('//*[@id="loginForm"]/div/div/div/div[2]/div[1]/div[2]').click() #登錄操作
sleep(2)
TipsMsg = self.dr.find_element_by_css_selector("#w_nav_temp_1000 > div.fr.dl > a:nth-child(4)").text
self.assertEqual(TipsMsg,"[退出]",msg="Test_login03 login exception")
if __name__ == '__main__':
unittest.main()
#執(zhí)行結(jié)果如下
"""
Test start...
...
Test end...
----------------------------------------------------------------------
Ran 3 tests in 25.253s
OK
"""
3、通過(guò)裝飾器跳過(guò)某條用例
添加裝飾器(@unittest.skip(""))
import unittest
class Test(unittest.TestCase):
def setUp(self) -> None:
print("---start---")
def tearDown(self) -> None:
print("---end---")
def testbbb(self):
print("case testbbb")
@unittest.skip("testaaa 被跳過(guò)")
def testaaa(self):
print("case testaaa")
if __name__ == '__main__':
unittest.main()
# 結(jié)果如下
s.
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK (skipped=1)
---start---
case testbbb
---end---
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python 實(shí)現(xiàn)mysql增刪查改示例代碼
python中可以通過(guò)pymysql實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)的連接,并實(shí)現(xiàn)數(shù)據(jù)庫(kù)的各種操作,這篇文章主要給大家介紹了關(guān)于pymsql實(shí)現(xiàn)增刪改查的示例代碼,需要的朋友可以參考下2021-11-11
python pytest進(jìn)階之conftest.py詳解
這篇文章主要介紹了python pytest進(jìn)階之conftest.py詳解,如果我們?cè)诰帉憸y(cè)試用的時(shí)候,每一個(gè)測(cè)試文件里面的用例都需要先登錄后才能完成后面的操作,那么們?cè)撊绾螌?shí)現(xiàn)呢?這就需要我們掌握conftest.py文件的使用了,需要的朋友可以參考下2019-06-06
10分鐘用python搭建一個(gè)超好用的CMDB系統(tǒng)
這篇文章主要介紹了10分鐘用python搭建一個(gè)超好用的CMDB系統(tǒng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
詳解使用django-mama-cas快速搭建CAS服務(wù)的實(shí)現(xiàn)
這篇文章主要介紹了詳解使用django-mama-cas快速搭建CAS服務(wù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
對(duì)python實(shí)現(xiàn)模板生成腳本的方法詳解
今天小編就為大家分享一篇對(duì)python實(shí)現(xiàn)模板生成腳本的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
使用Python和GDAL給圖片加坐標(biāo)系的實(shí)現(xiàn)思路(坐標(biāo)投影轉(zhuǎn)換)
這篇文章主要介紹了使用Python和GDAL給圖片加坐標(biāo)系的實(shí)現(xiàn)思路(坐標(biāo)投影轉(zhuǎn)換),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Python+Socket實(shí)現(xiàn)基于UDP協(xié)議的局域網(wǎng)廣播功能示例
這篇文章主要介紹了Python+Socket實(shí)現(xiàn)基于UDP協(xié)議的局域網(wǎng)廣播功能,結(jié)合實(shí)例形式分析了Python+socket實(shí)現(xiàn)UDP協(xié)議廣播的客戶端與服務(wù)器端功能相關(guān)操作技巧,需要的朋友可以參考下2017-08-08

