一、Unittest框架
????下面是最簡單的使用Unittest框架的方法,所有的內容都放在里面担敌,但是不利于后期維護。
????該使用了全局變量蝇裤,在這種只有一個測試集與用例的場合沒有問題,但是一個文件內有多個用例集與多個用例就會產生問題频鉴,要么使用在打開的瀏覽器器中栓辜,再打開一個頁面執(zhí)行其他用例,要么使用其他方法垛孔。
from selenium import webdriver
import unittest
#使用unittest必須先使用class定義一個類藕甩,且以Test開頭,并繼承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
# 必須使用@classmethod裝飾器似炎,這是使用tearDownClass與setUpClass的基本要求
#setUpClass表示下面的代碼Testbaidu_search測試集只會在開始時運行一次
@classmethod
def setUpClass(cls) -> None:
global driver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
def test_search(self):
driver.find_element_by_id('kw').send_keys('孔子')
driver.find_element_by_id('su').click()
@classmethod
# tearDownClass表示下面的代碼Testbaidu_search測試集只會在結束時運行一次
def tearDownClass(cls) -> None:
driver.quit()
if __name__ == '__main__':
unittest.main()
改進:
from selenium import webdriver
import time
import unittest
#使用unittest必須先使用class定義一個類,且以Test開頭悯姊,并繼承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
# 必須使用@classmethod裝飾器羡藐,這是使用tearDownClass與setUpClass的基本要求
#setUpClass表示下面的代碼Testbaidu_search測試集只會在開始時運行一次
@classmethod
def setUpClass(cls) -> None:
#由于setUpClass(cls)是一個類的方法,內部的變量可以被其他方法通過self.變量名訪問悯许,而cls仆嗦,只是代表setUpClass本身,與self是一樣的意思先壕,在其他方法內通過self調用訪問即可瘩扼。
cls.driver=webdriver.Chrome()
cls.driver.get('https://www.baidu.com/')
def test_search(self):
self.driver.find_element_by_id('kw').send_keys('孔子')
self.driver.find_element_by_id('su').click()
@classmethod
# tearDownClass表示下面的代碼Testbaidu_search測試集只會在結束時運行一次
def tearDownClass(cls) -> None:
time.sleep(3)
cls.driver.quit()
if __name__ == '__main__':
unittest.main()
二、ddt數(shù)據驅動
????打開ddt模塊的源代碼垃僚,發(fā)現(xiàn)使用ddt里面的方法需要在Unittest的testcase中間使用集绰,使用情形為裝飾器樣式。下面為常用方法:
- ddt????放在定義的測試集前面谆棺,表明這個測試集啟用數(shù)據驅動
- data(數(shù)據內容或者*數(shù)據變量)????放在測試方法前面栽燕,表明這個方法使用的是什么數(shù)據
- unpack????對data的數(shù)據進行解包
-
file_data(value, yaml_loader=None)????可以直接讀取yaml和json文件
附錄ddt數(shù)據驅動與Unittest結合的代碼:
from selenium import webdriver
from unittest import TestCase
import unittest
from ddt import ddt,data,unpack
import time
search_data=(['孔子'],['孟子'],['莊子'])
#使用裝飾器,表明該測試集采用ddt驅動
@ddt
#使用unittest必須先使用class定義一個類,且以Test開頭碍岔,并繼承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
# 必須使用@classmethod裝飾器浴讯,這是使用tearDownClass與setUpClass的基本要求
#setUpClass表示下面的代碼Testbaidu_search測試集只會在開始時運行一次
@classmethod
def setUpClass(cls) -> None:
global driver
driver=webdriver.Chrome()
driver.get('https://www.baidu.com/')
#data取數(shù)據
# @data(['孔子'],['孟子'],['莊子'])
#如果傳入的是一個變量接收的數(shù)據集,那么需要在變量前面加*
@data(*search_data)
#unpack解壓數(shù)據包
@unpack
#由于只有一個變量蔼啦,在測試用例用中榆纽,加入一個變量名,用于接收解壓到的數(shù)據捏肢,針對多個的情況后面再詳細說明
def test_search(self,value):
driver.find_element_by_id('kw').send_keys(value)
driver.find_element_by_id('su').click()
time.sleep(3)
driver.find_element_by_id('kw').clear()
#上面的用例思路可以用在需要反復輸入測試的場合
@classmethod
# tearDownClass表示下面的代碼Testbaidu_search測試集只會在結束時運行一次
def tearDownClass(cls) -> None:
driver.quit()
if __name__ == '__main__':
unittest.main(verbosity=2)
下圖可以看到奈籽,完成了三個測試用例,并且用例名自動加了1
????后續(xù)繼續(xù)更新添加斷言猛计,以及更加系統(tǒng)唠摹、更加實用的方法。以上內容僅能學習使用奉瘤,不完善勾拉,在工作中使用不方便,而且架構也不好盗温。
三藕赞、ddt中data與unpack的詳細講解
這里只中間部分代碼,即存在區(qū)別的地方:
方法一:將括號內的每個子列表視為一個數(shù)據卖局,在Unittest進行反復調用斧蜕,執(zhí)行用例
@data(['孔子'],['孟子'],['莊子'])
方法二:data里面存在一個列表(列表內多個數(shù)據),需要使用unpack解一次包
@data(['孔子', '孟子', '莊子'])
@unpack
方法三:變量接收的數(shù)據需要需要此格式解包:@data(*變量名)
#我定義了一個讀取csv文件的函數(shù)砚偶,得到的結果是一個列表批销,這個函數(shù)在后續(xù)的(二)中講解
#以下代碼等同于直接賦值:search_data=['孔子','孟子','莊子']
search_data=read_csv('CVS數(shù)據表.csv',col_name='name')
#函數(shù)返回:['孔子','孟子','莊子']
#解包
@data(*search_data)
方法四:多重解包
下面代碼會列表視為一個數(shù)據進行迭代
import unittest
from ddt import ddt,data,unpack
@ddt
#使用unittest必須先使用class定義一個類,且以Test開頭染坯,并繼承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
def setUp(self) -> None:
pass
data_file=(['孔子', '孟子', '莊子'],['老子', '孫武', '靜靜'])
@data(*data_file)
def test_jiebao(self,value):
print(value)
def tearDown(self) -> None:
pass
if __name__ == '__main__':
unittest.main(verbosity=2)
結果:
['孔子', '孟子', '莊子']
['老子', '孫武', '靜靜']
方法五:
@ddt
#使用unittest必須先使用class定義一個類均芽,且以Test開頭,并繼承unittest.TestCase
class Testbaidu_search(unittest.TestCase):
def setUp(self) -> None:
pass
data_file=(['孔子', '孟子', '莊子'],['老子', '孫武', '靜靜'])
@data(*data_file)
@unpack
def test_jiebao(self,name1,name2,name3):
print(name1)
print(name2)
print(name3)
def tearDown(self) -> None:
pass
if __name__ == '__main__':
unittest.main(verbosity=2)
結果:
說明:
????上面的這種方法用于多數(shù)據的情況单鹿,如注冊用戶測試用例掀宋,不會造成用例文檔很長,使界面變的更加簡潔:
csv格式:
acount,result
[用戶名仲锄,密碼],pass
學習之路漫漫劲妙,愿你我一路共勉!