參考學(xué)習(xí)官網(wǎng)文檔:https://docs.pytest.org/en/latest/getting-started.html
一嫌褪、pytest簡(jiǎn)介
1. 前言:測(cè)試框架與測(cè)試工具
- 測(cè)試框架、測(cè)試工具這兩個(gè)概念經(jīng)常容易搞混了医咨,測(cè)試框架是諸如 Unittest、Pytest、TestNG 這類烛亦,而測(cè)試工具指的則是 Selenium射富、Appium解虱、Jmeter 這類费变。
- 測(cè)試框架的作用是未玻,幫助管理測(cè)試用例、執(zhí)行測(cè)試用例胡控、參數(shù)化、斷言旁趟、生成測(cè)試報(bào)告等基礎(chǔ)性工作昼激,讓我們將精力用在測(cè)試用例的編寫(xiě)上。好的測(cè)試框架應(yīng)該具有很高的擴(kuò)展性锡搜,支持二次開(kāi)發(fā)橙困,并能夠支持多種類型的自動(dòng)化測(cè)試。
- 測(cè)試工具的作用是為了完成某一類型的測(cè)試耕餐,比如 Selenium 用于對(duì) WEB UI 進(jìn)行自動(dòng)化測(cè)試凡傅,Appium 用來(lái)對(duì) APP 進(jìn)行自動(dòng)化測(cè)試,Jmeter 可以用來(lái)進(jìn)行 API 自動(dòng)化測(cè)試和性能測(cè)試肠缔。另外夏跷,Java 語(yǔ)言中 OkHttp 庫(kù)哼转,Python 語(yǔ)言中的 requests 庫(kù),這些 HTTP 的 client 也可以看做是一種 API 測(cè)試工具槽华。
2. 單元測(cè)試框架
- 1)什么是單元測(cè)試框架壹蔓?
單元測(cè)試是指軟件開(kāi)發(fā)中,針對(duì)軟件的最小單位(函數(shù)猫态、方法)進(jìn)行正確性的檢查測(cè)試佣蓉,Java:junit、testing
Python:unittest亲雪、pytest- 2)單元測(cè)試框架主要做什么勇凭?
① 測(cè)試發(fā)現(xiàn):從多個(gè)文件里面去找我們得測(cè)試用例
② 測(cè)試執(zhí)行:按照一定的順序和規(guī)則去執(zhí)行,并生成結(jié)果
③ 測(cè)試判斷:通過(guò)斷言判斷預(yù)期結(jié)果和實(shí)際結(jié)果的差異
④ 測(cè)試報(bào)告:統(tǒng)計(jì)測(cè)試進(jìn)度义辕、耗時(shí)虾标、通過(guò)率、生成測(cè)試報(bào)告
3. pytest簡(jiǎn)介
- Pytest 是 Python 的一種易用终息、高效和靈活的單元測(cè)試框架夺巩,可以支持單元測(cè)試和功能測(cè)試
- pytest可以和selenium,requests周崭,appium結(jié)合實(shí)現(xiàn)web自動(dòng)化柳譬、接口自動(dòng)化、app自動(dòng)化
- pytest可以實(shí)現(xiàn)測(cè)試用例的跳過(guò)以及reruns(失敗用例重試)
- pytest可以和allure生成非常美觀的測(cè)試報(bào)告
- pytest可以和jenkins持續(xù)集成
- pytest有很多非常強(qiáng)大的插件续镇,并且這些插件能夠?qū)崿F(xiàn)很多實(shí)用的操作
① pytest-xdist:測(cè)試用例分布式執(zhí)行美澳,多cpu分發(fā)
② pytest-ordering:用于改變測(cè)試用例的執(zhí)行順序
③ pytest-rerunfailures:用例失敗后重跑
④ pytest-html:生成html格式的自動(dòng)化測(cè)試報(bào)告
⑤ allure-pytest:用于生成美觀測(cè)試報(bào)告
二、安裝pytest
pytest需要:Python 3.7+ 或 PyPy3
- 在命令行中運(yùn)行以下命令
pip install -U pytest
其他插件安裝方法也是一樣pip安裝
-
檢查是否安裝成功pytest
三摸航、pytest使用規(guī)則
- 模塊名必須以
test_
開(kāi)頭或test_
結(jié)尾 - 測(cè)試類必須以
Test
開(kāi)頭制跟,且不能有init
方法 - 測(cè)試方法必須以
test
開(kāi)頭
使用規(guī)則
四、測(cè)試用例執(zhí)行
pytest 用例的執(zhí)行主要有以下三種方式:
- 通過(guò)命令模式執(zhí)行
- 通過(guò)主函數(shù)執(zhí)行
- 通過(guò)讀取 pytest.ini 配置文件執(zhí)行
4.1 通過(guò)命令模式執(zhí)行
測(cè)試文件test_demo.py:Pytest 使用 Python 的 assert
進(jìn)行條件判斷酱虎,簡(jiǎn)單的測(cè)試函數(shù)如:
def test_product_case001():
print("模擬測(cè)試模塊1的功能")
assert 1 + 1 == 3
def test_product_case002():
print("模擬測(cè)試模塊2的功能")
assert 1 == 1
1)執(zhí)行所有用例
pytest
命令執(zhí)行當(dāng)前目錄下所有的測(cè)試用例雨膨,所以要想執(zhí)行項(xiàng)目中所有的用例,只需要將執(zhí)行目錄切換到根目錄即可:
可以加上-v參數(shù)查看詳情pytest -v
2)指定執(zhí)行
執(zhí)行指定目錄:4.2 通過(guò)主函數(shù)執(zhí)行
1)主函數(shù)運(yùn)行
test_demo.py添加主函數(shù):
import pytest
class Testdemo:
def test_case_passed(self):
print("模擬執(zhí)行成功場(chǎng)景的case")
assert (1, 2, 3) == (1, 2, 3)
def test_case_failed():
print("模擬執(zhí)行失敗場(chǎng)景的case")
assert 3 == 1 + 1
if __name__ == '__main__':
pytest.main(["-v"]) # 執(zhí)行測(cè)試用例读串,-v參數(shù)打印詳細(xì)信息
然后直接運(yùn)行:從終端的打印可以看到聊记,用例文件中的用例方法 test_case_failed
以及測(cè)試類中的測(cè)試方法 test_case_passed
都被執(zhí)行了。
2)批量執(zhí)行
只需要在對(duì)應(yīng)的用例文件中調(diào)用主函數(shù)恢暖,就可以自動(dòng)執(zhí)行文件中的所有用例排监。
但是在實(shí)際的使用中,一般會(huì)將用例分類寫(xiě)在不同目錄下的不同用例文件里杰捂,且執(zhí)行時(shí)要批量去執(zhí)行所有的用例舆床,所以往往會(huì)將主函數(shù)寫(xiě)在一個(gè)與用例文件夾平級(jí)的 py 文件中,pytest 內(nèi)部設(shè)有對(duì)應(yīng)的機(jī)制,會(huì)自動(dòng)掃描全局挨队,執(zhí)行所有的用例文件谷暮。
運(yùn)行主函數(shù)文件main.py
,輸出結(jié)果可以看到所有用例均被執(zhí)行了:
3)指定執(zhí)行
pytest.main()可以加上命令參數(shù)運(yùn)行瞒瘸,如下
4.3 通過(guò) pytest.ini 配置文件執(zhí)行
在項(xiàng)目中坷备,通常通過(guò)配置全局的配置文件來(lái)執(zhí)行測(cè)試用例的。其余兩種執(zhí)行方式在編寫(xiě)和調(diào)試用例時(shí)比較方便情臭。對(duì)于配置文件省撑,有以下幾點(diǎn)要求:
- 配置文件的名字必須為 pytest.ini
- 配置文件一般放置在項(xiàng)目的根目錄
- 配置文件必須時(shí) ANSI 編碼
- 配置了pytest.ini文件后,不管是主函數(shù)模式運(yùn)行用例俯在,還是命令行模式運(yùn)行用例竟秫,都會(huì)去讀取pytest.ini配置文件中的內(nèi)容。
- CMD命令行中執(zhí)行pytest -h命令跷乐,可以查看pytest.ini的設(shè)置選項(xiàng)肥败。
pytest.ini 是 pytest 框架的核心配置文件,它可以改變 pytest 的默認(rèn)行為愕提,不管是通過(guò)主函數(shù)還是命令模式去執(zhí)行用例馒稍,都會(huì)先去讀取配置文件。
五纽谒、執(zhí)行參數(shù)
我們?cè)趫?zhí)行用例時(shí),可以通過(guò)添加相關(guān)的參數(shù)實(shí)現(xiàn)不同的執(zhí)行效果如输,提升測(cè)試效率鼓黔。
1)-s:用于輸出調(diào)試信息,包括打印輸出的信息
# 通過(guò)main函數(shù)執(zhí)行
pytest.main(["-s", "./product_cases/test_product.py"])
# 通過(guò)命令模式執(zhí)行
pytest -s ./product_cases/test_product.py
2)-v:顯示更詳細(xì)的信息
# 通過(guò)main函數(shù)執(zhí)行
pytest.main(["-v", "./product_cases/test_product.py"])
# 通過(guò)命令模式執(zhí)行
pytest -v ./product_cases/test_product.py
3)-vs:將 -v 和 -s 參數(shù)效果結(jié)合不见,推薦使用
-vs
4)-n:支持多線程或者分布式運(yùn)行測(cè)試用例
n是進(jìn)程數(shù)澳化,也就是cpu個(gè)數(shù),最大值為當(dāng)前機(jī)器cpu個(gè)數(shù)稳吮,也可以設(shè)置為auto缎谷,自動(dòng)識(shí)別cpu個(gè)數(shù)。
# 通過(guò)main函數(shù)執(zhí)行
# 開(kāi)兩個(gè)線程去執(zhí)行用戶操作目錄下所有的用例
pytest.main(["-vs", "./product_cases", "-n=2"])
# 通過(guò)命令模式執(zhí)行
pytest -vs ./product_cases -n 2
為了方便看出測(cè)試效果灶似,給test_product.py文件中的每個(gè)測(cè)試用例都增加sleep(2)
import pytest,time
def test_product_case001():
time.sleep(2)
print("模擬測(cè)試模塊1的功能")
assert 1 + 1 == 2
def test_product_case002():
time.sleep(2)
print("模擬測(cè)試模塊2的功能")
assert 1 == 1
正常執(zhí)行結(jié)果:用時(shí)4.05s5)--reruns:失敗用例重跑
# 通過(guò)main函數(shù)執(zhí)行
# 如果用例執(zhí)行失敗慎陵,該用例再執(zhí)行2次
pytest.main(["-vs", "./product_cases", "--reruns=2"])
# 通過(guò)命令模式執(zhí)行
pytest -vs ./product_cases --reruns 2
修改test_product.py文件
def test_product_case001():
print("模擬測(cè)試模塊1的功能")
assert 1 + 1 == 3
def test_product_case002():
print("模擬測(cè)試模塊2的功能")
assert 1 == 1
6)-x:只要有一個(gè)用例失敗,就停止執(zhí)行
# 通過(guò)main函數(shù)執(zhí)行
pytest.main(["-vs", "./product_cases", "-x"])
# 通過(guò)命令模式執(zhí)行
pytest -vs ./product_cases -x
test_product_case001
失敗喻奥,停止執(zhí)行,test_product_case002
未執(zhí)行
7)--maxfail:失敗的用例數(shù)達(dá)到規(guī)定值時(shí)停止測(cè)試
# 失敗的用例數(shù)達(dá)到2個(gè)時(shí)停止測(cè)試
# 通過(guò)main函數(shù)執(zhí)行
pytest.main(["-vs", "./product_cases", "--maxfail=2"])
# 通過(guò)命令模式執(zhí)行
pytest -vs ./product_cases --maxfail 2
8)-k:關(guān)鍵字過(guò)濾執(zhí)行
-k會(huì)匹配文件名捏悬、類名撞蚕、方法名匹配表達(dá)式的用例,如果指定的表達(dá)式是被文件名/測(cè)試類名包含的过牙,那么文件/測(cè)試類中所有的測(cè)試方法都會(huì)被執(zhí)行甥厦。
# 執(zhí)行文件名/類名/方法名中包含01的用例
# 通過(guò)main函數(shù)執(zhí)行
pytest.main(["-vs", "./product_cases", "-k=01"])
# 通過(guò)命令模式執(zhí)行
pytest -vs ./product_cases -k="01"
指定執(zhí)行測(cè)試用例名稱包含01
:
指定執(zhí)行測(cè)試用例名稱包含login
:
9)--html:用例執(zhí)行完成后生成 html 格式的測(cè)試報(bào)告
pytest -vs --html ./report/result.html
--html+報(bào)告存放路徑參數(shù)
六纺铭、用例執(zhí)行順序
修改 test_product.py 中測(cè)試方法:
def test_product_case():
print("模擬測(cè)試產(chǎn)品相關(guān)的操作")
def test_case_001():
print("測(cè)試方法_001")
def test_case_002():
print("測(cè)試方法_002")
def test_case_003():
print("測(cè)試方法_003")
def test_case_004():
print("測(cè)試方法_004")
def test_case_005():
print("測(cè)試方法_005")
1)默認(rèn)執(zhí)行順序
pytest 對(duì)于用例的執(zhí)行順序是按照從上到下執(zhí)行的
2) 改變用例的執(zhí)行順序
通過(guò)裝飾器方法@pytest.mark.run()
可以改變用例的執(zhí)行順序,參數(shù)order=n指定排在第n個(gè)執(zhí)行
# product_cases/test_product.py
import pytest
def test_product_case():
print("模擬測(cè)試產(chǎn)品相關(guān)的操作")
# 通過(guò)裝飾器方法 @pytest.mark.run() 可以改變用例的執(zhí)行順序
# order參數(shù)表示該用例要排在第幾個(gè)執(zhí)行
@pytest.mark.run(order=1)
def test_case_002():
print("測(cè)試方法_002")
@pytest.mark.run(order=2)
def test_case_003():
print("測(cè)試方法_003")
def test_case_004():
print("測(cè)試方法_004")
def test_case_005():
print("測(cè)試方法_005")
從終端輸出的結(jié)果可以看到刀疙,被裝飾器裝飾的測(cè)試用例都按照了指定的順序執(zhí)行舶赔,沒(méi)有被裝飾到的用例還是按照從上到下的順序執(zhí)行
七、標(biāo)記函數(shù)谦秧,分組執(zhí)行用例
1)裝飾器@pytest.mark.name
裝飾用例
第一步竟纳,使用裝飾器@pytest.mark.name
去裝飾要執(zhí)行的用例,其中 name 為自定義的名稱
# product_cases/test_product.py
import pytest
# 通過(guò)裝飾器方法 @pytest.mark.finished標(biāo)記已完成的用例
@pytest.mark.finished
def test_product_case():
print("模擬測(cè)試產(chǎn)品相關(guān)的操作")
# 通過(guò)裝飾器方法 @pytest.mark.unfinished標(biāo)記未完成功能的用例
@pytest.mark.unfinished
def test_case_002():
print("測(cè)試方法_002")
@pytest.mark.unfinished
def test_case_003():
print("測(cè)試方法_003")
def test_case_004():
print("測(cè)試方法_004")
def test_case_005():
print("測(cè)試方法_005")
2)pytest.ini 添加分組配置
第二步疚鲤,去 pytest.ini 中添加分組配置锥累,配置名必須和裝飾器中的 name 值一致3)參數(shù) -m 指定執(zhí)行用例
第三步,執(zhí)行時(shí)通過(guò)參數(shù) -m 指定要執(zhí)行的用例八集歇、跳過(guò)用例
對(duì)于某些不想執(zhí)行的用例桶略,可以使用 pytest 提供的裝飾器方法@pytest.mark.skip()
跳過(guò)該用例不去執(zhí)行
1)直接跳過(guò)
裝飾器語(yǔ)法:@pytest.mark.skip(reason="")
,reason 參數(shù)可選诲宇,表示跳過(guò)該測(cè)試方法的原因
2)條件跳過(guò)
裝飾器語(yǔ)法:@pytest.mark.skipif(判斷條件, reason="")
际歼,為測(cè)試函數(shù)指定被忽略的條件,reason 參數(shù)可選
# product_cases/test_product.py
import pytest
version = 1
# V2版本才支持姑蓝,版本小于V2則跳過(guò)不執(zhí)行
@pytest.mark.skipif(version < 2, reason='not supported until v2')
def test_product_case():
print("模擬測(cè)試產(chǎn)品相關(guān)的操作")
def test_case_001():
print("測(cè)試方法_001")
def test_case_002():
print("測(cè)試方法_002")
-
version=1滿足條件鹅心,跳過(guò)不執(zhí)行滿足條件跳過(guò)
-
version=2不滿足條件,不跳過(guò)執(zhí)行不滿足條件不跳過(guò)
文章轉(zhuǎn)載參考:http://www.chendacheng.com/content/?category=Pytest%E4%B8%93%E9%A2%98&article=Pytest_01.html