【pytest】基本使用
pytest基本介紹
pytest是一個非常成熟的全功能的Python測試框架,主要特點有以下幾點:
- 簡單靈活,容易上手;
- 支援引數化;
- 能夠支援簡單的單元測試和複雜的功能測試,還可以用來做selenium/appnium等自動化測試、介面自動化測試(pytest+requests);
- pytest具有很多第三方外掛,並且可以自定義擴充套件,比較好用的如pytest-selenium(整合selenium)、pytest-html(html測試報告生成)、pytest-rerunfailures(失敗case重複執行)、pytest-xdist(多CPU分發)、allure-pytest(生成測試報告)等;
- 測試用例的skip和xfail處理;
- 可以很好的和jenkins整合;
- pytest預設執行順序是按照case順序位置先後執行的;
- pytest.ini和conftest.py檔案要放在執行的同級目錄(根目錄)
識別case的規則
- 如果pytest命令列有指定目錄,則從該目錄中開始查詢測試用例檔案,如果沒有指定,則從當前執行目錄開始查詢檔案。注意,該查詢是遞迴查詢,子目錄中的檔案也會被查詢到。
- 並不是能夠查詢到目錄下的所有檔案,只有符合命名規則的檔案才會被查詢。預設規則是以test_開頭或者以_test結尾的.py檔案。
- 在測試檔案中查詢Test開頭的類,以及類中以test_開頭的方法,查詢測試檔案中test_開頭的函式
setup&teardown使用
- 模組級(setup_module/teardown_module)開始於模組始末呼叫,全域性的
- 函式級(setup_function/teardown_function)只對函式用例生效,在函式始末呼叫(不在類中,在類外部)
- 類級(setup_class/teardown_class)在類始末呼叫
- 方法級(setup_method/teardown_method)在方法始末呼叫(在類中)
- 方法級(setup/teardown)在方法始末呼叫(在類中)
- yield:yield前相當於setup,yield後相當於teardown,scpoe="module"與yield組合,相當於setup_module和teardown_module
注意呼叫順序:
setup_module>setup_class>setup_method>setup>teardown>teardown_method>teardown_class>teardown_module
安裝以及常用的外掛
pytest安裝
pip install pytest
生成html報告
pip install pytest-html
pytest --html=path/to/html/report.html
如果不新增–self-contained-html引數,生成報告的css檔案是獨立的,分享的時候容易資料丟失
失敗後重跑
pip install pytest-rerunfailures
命令列引數:
pytest --reruns 重試次數 (--reruns-delay 次數之間間隔)
pytest --reruns 2 執行失敗的用例可以執行2次
pytest --reruns 2 --reruns-delay 5 執行失敗的用例可以執行2次,每次間隔5秒
pytest.main(['-vs', 'test_demo.py',"--reruns", "3"])
只對部分用例使用重新執行機制
pip install flaky
@pytest.mark.flaky(reruns=5, reruns_delay=2)
#reruns=5, reruns_delay=2:最多失敗重跑5次 & 如果失敗則延遲2秒後重跑(可以不傳)
@flaky(max_runs=3, min_passes=2)
#第一次執行失敗了,將會再次重複執行它3次,如果這3次中有2次成功了,則認為這個測試通過了。
通過allure生成報告
pip install allure-pytest
併發執行case
pip install pytest-xdist
#多個cpu併發執行用例,需要在pytest後新增引數-n,如果引數為auto,則會自動檢測系統cpu個數。如果引數為數字,則指定執行測試用例的處理器程序數
命令列引數:
pytest -n auto
pytest -n [num]
# 配置在pytes.ini檔案內用法
[pytest]
addopts = -n 3
yaml引數化
pip install PyYAML
此外還有很多很好的第三方外掛,到 http://plugincompat.herokuapp.com/ 和 https://pypi.python.org/pypi?%3Aaction=search&term=pytest-&submit=search進行查詢。
執行指定case
pytest.main() #執行所有case
pytest.main(['-vs', 'TestCalc.py::TestCalc']) #執行TestCalc.py檔案內TestCalc類下所有case
pytest.main(['-vs', 'TestCalc.py::TestCalc::test_division_seven']) #執行TestCalc.py檔案內TestCalc類下名字為test_division_seven的case
pytest.main(['引數','xxx']) pytest.main()內必須是list格式,在低版本已不支援str
執行case時可選引數
-v: #列印詳細執行的日誌資訊
-s: pytest -s xxx.py #輸出case中print的內容
-m: pytest -m “tag名稱” #執行指定tag名稱的用例,也就是執行有@pytest.mark.[標記名]這個標記的case
-k: # pytest -k “類名、方法名、類名 and not 方法名” #執行指定case的用例
-x: #遇到失敗的case就是停止執行
--lf: #只重新執行上次執行失敗的用例(或如果沒有失敗的話會全部跑)
--ff: #執行所有測試,但首先執行上次執行失敗的測試(這可能會重新測試,從而導致重複的fixture setup/teardown)
--maxfail=num: #當用例失敗個數達到num時,停止執行
--collect-only: #收集測試用例,展示出哪些用例會被執行(只是展示不會執行case)
--junit-xml:--junit-xml=path/name.xml #在指定目錄或當前目錄下生成xml格式的報告(需要在pytest.ini檔案內宣告格式:junit_family=xunit2)
--steup-show #完整展示每個用例的fixture呼叫順序
命令列執行:
pytest test_quick_start.py --junit-xml=report.xml
main執行:
pytest.main(["-s", "TestCalc.py", "-m", "div", "--junit-xml=report.xml"])
pytest.main(["-vsx", "TestCalc.py", "-m", "div"])
用例標籤tags:@pytest.mark.{marker_name}
@pytest.mark.{marker_name}自定義一個mark,然後pytest -v -m {marker_name}只執行標記了{marker_name}的函式,pytest -v -m "not {marker_name}"來執行未標記{marker_name}的。
注意:必須在pytest.ini檔案內宣告標籤,不然則會告警PytestUnknownMarkWarning
pytest.ini
markers =
div
tag
語法:
@pytest.mark.smoke
@pytest.mark.get
$pytest -m 'smoke'
僅執行標記smoke的函式
$pytest -m 'smoke and get'
執行標記smoke和get的函式
$pytest -m 'smoke or get'
執行標記smoke或get的函式
$pytest -m 'smoke and not get'
執行標記smoke和標記不是get的函式