PyTest是基於Python的開源測試框架,語法簡單易用,有大量的插件,功能非常多。自動檢測測試用例,支持參數化,跳過特定用例,失敗重試等功能。
目錄
安裝
使用pip命令安裝:
pip install -U pytest # 安裝
pytest --version # 查看版本
pytest -h # 查看幫助信息
$ pytest --version
pytest 6.2.4
用例識別
- pytest識別文件名為test_*.py或者*_test.py的測試文件
- 測試文件中可以在Test*類中寫測試用例(測試用例以test_*開頭,並且測試類不能有__init__方法)
- 不在Test*類中的test_*用例也可以被識別到。
打印測試目錄下匹配到的所有用例:pytest --collect-only
(base) D:\ProgramWorkspace\TestingDemo>pytest --collect-only
============================================== test session starts ==============================================
platform win32 -- Python 3.7.6, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: D:\ProgramWorkspace\TestingDemo
plugins: hypothesis-5.5.4, arraydiff-0.3, astropy-header-0.1.2, doctestplus-0.5.0, openfiles-0.4.0, remotedata-0.3
.2
collected 20 items
<Module test_pytest.py>
<Function test_one>
<Function test_two>
<Function test_three>
<Module test_pytest2.py>
<Class Test_Demo>
<Function test_one>
<Function test_two>
<Function test_three>
<Package D:\ProgramWorkspace\TestingDemo\testing>
<Module test_calc.py>
<UnitTestCase TestCalc>
<TestCaseFunction test_add_1>
<TestCaseFunction test_add_2>
<Module test_calc2.py>
<Class TestCalc>
<Function test_add[1-2-3]>
<Function test_add[-1--2--3]>
<Function test_add[0-1-1]>
<Function test_add[0--1--1]>
<Function test_add[0.1-0.2-0.3]>
<Function test_add[999999-1000000-1999999]>
<Function test_div[1-2-0.5]>
<Function test_div[-1--2-0.5]>
<Function test_div[0-1-0]>
<Function test_div[1-0-0]>
<Function test_div[0.1-0.2-0.5]>
<Function test_add_1>
常用選項
-V, --version
:查看版本信息-h, --help
:查看幫助信息-k EXPRESSION
:運行EXPRESSION匹配到的用例,例如pytest -k "add"
運行文件名包含add
的用例。-m MARKEXPR
:執行標記的用例-x, --exitfirst
:報錯就停止--maxfail=num
:錯誤數達到num時停止--lf, --last-failed
:僅運行上次執行失敗的用例,上一次執行失敗的用例記錄在.pytest_cache/v/cache/lastfailed文件中--ff, --failed-first
:運行所以用例,但是先運行上一次執行失敗的用例-s
:命令行顯示輸出日志,加上它之后可以顯示代碼中print打印內容-v, --verbose
:打印詳細日志信息-q, --quiet
:打印簡略日志信息--collect-only, --co
:僅收集測試用例,不執行
Pytest用例執行
用例執行
一個簡單的測試用例test_pytest.py:
import pytest
def calc(a,b):
return a + b
class TestDemo():
def test_answer1(self):
assert calc(1, 1) == 2
def test_answer2(self):
assert calc(2, 1) == 3
@pytest.mark.answer3
def test_answer3(self):
assert calc(6, 6) == 12
if __name__=='__main__':
pytest.main()
可以使用如下方式執行某個測試用例
# 執行test_pytest.py所有用例(模塊)
pytest test_pytest.py
# 執行test_pytest.py里的TestDemo類
pytest test_pytest.py::TestDemo
# 執行test_pytest.py里的TestDemo類的test_answer2方法
pytest test_pytest.py::TestDemo::test_answer2
打印日志信息
# 打印詳細運行日志信息
pytest -v test_pytest.py
pytest -s test_pytest.py
跳過某個用例
# 跳過運行某個用例
pytest -v -k "類名 and not方法名" 文件名
pytest -v -k "TestDemo and not test_answer2" test_pytest.py
運行文件名包含某個關鍵字的用例
識別包含“add”的用例:pytest -k "add" --collect-only
(base) D:\ProgramWorkspace\TestingDemo>pytest -k "add" --collect-only
============================================== test session starts ==============================================
platform win32 -- Python 3.7.6, pytest-5.3.5, py-1.8.1, pluggy-0.13.1
rootdir: D:\ProgramWorkspace\TestingDemo
plugins: hypothesis-5.5.4, arraydiff-0.3, astropy-header-0.1.2, doctestplus-0.5.0, openfiles-0.4.0, remotedata-0.3
.2
collected 20 items / 11 deselected / 9 selected
<Package D:\ProgramWorkspace\TestingDemo\testing>
<Module test_calc.py>
<UnitTestCase TestCalc>
<TestCaseFunction test_add_1>
<TestCaseFunction test_add_2>
<Module test_calc2.py>
<Class TestCalc>
<Function test_add[1-2-3]>
<Function test_add[-1--2--3]>
<Function test_add[0-1-1]>
<Function test_add[0--1--1]>
<Function test_add[0.1-0.2-0.3]>
<Function test_add[999999-1000000-1999999]>
<Function test_add_1>
運行某個標記的用例
# 將運行有這個標記的測試用例:@pytest.mark.[標記名]
pytest -m [標記名] 文件名
pytest -m answer3 test_pytest.py
報錯停止
# 一旦運行到報錯用例就停止運行
pytest -x 文件名
pytest -x test_pytest.py
# 當報錯達到num的時候就停止運行
pytest --maxfail=[num] 文件名
pytest --maxfail=[num] test_pytest.py
失敗重新運行
安裝 pytest-rerunfailures 插件:
pip install pytest-rerunfailures
測試失敗后重新運行n次,在重新運行間延遲n秒再運行:
# 重新運行3次
pytest --reruns 3 -v -s test_pytest.py
# 重新運行5次,延遲1s
pytest --reruns 5 --reruns-delay 1 -v test_pytest.py
重復執行
安裝pytest-repeat插件
pip install pytest-repeat
重復執行:
# 重新執行3次
pytest -v -s --count=3 test_pytest.py
# 設置重復范圍:session, module, class或者function(默認)
pytest -v -s --count=3 --repeat-scope=session test_pytest.py
或者在代碼中標記:
import pytest
def calc(a,b):
return a + b
class TestDemo():
@pytest.mark.repeat(3)
def test_answer1(self):
assert calc(1, 1) == 2
多條斷言
一個方法中有多條斷言,通常第一條失敗后下面就不執行了,pytest-assume插件可以解決斷言失敗后繼續執行斷言的問題。
安裝
pip install pytest-assume
執行多條斷言:
# 寫法1
pytest.assume(x == y)
pytest.assume(True)
pytest.assume(False)
# 寫法2
with assume: assert calc(2, 1) == 4
with assume: assert calc(2, 1) == 3
with assume: assert calc(2, 2) == 3
修改測試用例test_pytest.py:
import pytest
from pytest import assume
def calc(a,b):
return a + b
class TestDemo():
def test_answer1(self):
assert calc(1, 1) == 2
def test_answer2(self):
with assume: assert calc(2, 1) == 4
with assume: assert calc(2, 1) == 3
with assume: assert calc(2, 2) == 3
@pytest.mark.answer3
def test_answer3(self):
assert calc(6, 6) == 12
if __name__=='__main__':
pytest.main()
測試結果:
pytest.main()
除了在終端執行外,也可以通過pytest.main()來執行,pytest.main() 自動查找當前目錄下以test_開頭的文件或者以_test結尾的py文件。
括號內可傳入執行參數,通過[]進行分割,[]內的多個參數通過逗號分割,所有的參數和pytest命令行方式一樣:
pytest.main(['-v', 'test_pytest.py']) # 執行test_pytest.py用例
或者直接在測試文件最后寫如下代碼,執行py文件。
if __name__=='__main__':
pytest.main()
# pytest.main(['-v', 'test_pytest.py'])
更多pytest執行方法可參考官方文檔:https://docs.pytest.org/en/latest/contents.html#toc
歡迎關注公眾號:「測試開發小記」及時接收最新技術文章!