pytest 基础使用
官网
https://docs.pytest.org/en/6.2.x/
默认规则:
- 文件以test_开头或者以_test结尾
- 类必须以Test开头
- 方法test开头(这样些用例也可以执行),规范写法是test_开头
函数形式
# test_测试函数形式.py
import pytest
def test_func1():
print("我是测试函数形式")
if __name__ == "__main__":
# -s : 捕捉测试方法输出信息,不加可以。
# 如果在命令行运行会执行当前路径下所有符合要求的测试用例:
# * 文件以test开头,类以Test开头,方法以test开头
pytest.main(['-s'])
类形式
pytest.main() : 中指定文件,只运行该文件的测试用例
# test_测试类形式.py
import pytest
class TestDemo:
def test_func1(self):
print("测试函数1 ")
def test_func2(self):
print("测试函数2")
if __name__ == '__main__':
# main() 中指定文件名,只运行指定文件中的测试用例
pytest.main(['-s', 'test_测试类形式.py'])
测试固件
测试固件 | 说明 |
---|---|
setup_moudle/teardown_moudle | 用于模块的始末,只执行一次 |
setup_function/teardown_function | 方法开始和结束处执行,只对类外的函数生效,不用在类中 |
setup_method/teardown_method | 在类中每个的方法开始和结束处执行 |
setup/teardown | 在每个方法开始和结束处执行,可以用在类内和类外 |
命令行窗口执行
1) 执行当前目录所有测试用例
进入目标目录,然后直接执行pytest
即可自动寻找到当前目录下的测试用例
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 5 items
test_测试函数形式.py . [ 20%]
test_测试类形式.py .. [ 60%]
case\test_case1.py .. [100%]
================================================================ 5 passed in 0.03s ================================================================
2) 执行指定的用例文件
pytest + 文件名
执行指定的用例
3) 执行指定用例类和方法
pytest 文件名::类名::方法名
执行指定的用例
PS E:\PyProject\demo\pytest> pytest .\test_测试类形式.py::TestDemo::test_func1
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 1 item
test_测试类形式.py . [100%]
================================================================ 1 passed in 0.01s ================================================================
命令行执行的参数
-x: 出现以一条测试用例失败就退出测试, 剩余的用例不会执行
PS E:\PyProject\demo\pytest> pytest -x .\test_测试类形式.py
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 2 items
test_测试类形式.py F
==================================================================== FAILURES =====================================================================
_______________________________________________________________ TestDemo.test_func1 _______________________________________________________________
self = <test_测试类形式.TestDemo object at 0x00000291ED1CEFB0>
print("测试函数1 ")
> assert 1 > 2
E assert 1 > 2
test_测试类形式.py:9: AssertionError
-------------------------------------------------------------- Captured stdout call ---------------------------------------------------------------
测试函数1
============================================================= short test summary info =============================================================
FAILED test_测试类形式.py::TestDemo::test_func1 - assert 1 > 2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================ 1 failed in 0.06s ================================================================
pytest -v 等价于 pytest --verbose(冗长)
PS E:\PyProject\demo\pytest> pytest --verbose
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- E:\PyProject\py_basic\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.1', 'Platform': 'Windows-10-10.0.19042-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins
': {'html': '3.1.1', 'metadata': '1.11.0', 'ordering': '0.6', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'E:\\code_tool\\java\\jdk1.8.0_311'}
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 5 items
test_测试类形式.py::TestDemo::test_func1 PASSED [ 20%]
test_测试类形式.py::TestDemo::test_func2 PASSED [ 40%]
测试函数形式_test.py::test_func1 PASSED [ 60%]
case/test_case1.py::TestDemo::test_func1 PASSED [ 80%]
case/test_case1.py::TestDemo::test_func2 PASSED [100%]
================================================================ 5 passed in 0.02s ================================================================
-q: 减少测试的运行冗长,输出的信息十分简洁,不会显示执行了哪些类方法,只有测试的通过数量和失败数量
PS E:\PyProject\demo\pytest> pytest -q
..... [100%]
5 passed in 0.03s
-s: 显示程序中 print语句 中的输出
-k: 模糊匹配, 后面可以跟文件名,在指定文件中进行匹配,也可以不跟文件名,在当前目录及子目录匹配
用法一:匹配方法名,不指定文件名,注意大小写:
PS E:\PyProject\demo\pytest> pytest -v -k test_a
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- E:\PyProject\py_basic\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.1', 'Platform': 'Windows-10-10.0.19042-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins
': {'html': '3.1.1', 'metadata': '1.11.0', 'ordering': '0.6', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'E:\\code_tool\\java\\jdk1.8.0_311'}
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 9 items / 5 deselected / 4 selected
test_测试类形式.py::TestDemo::test_a PASSED [ 25%]
test_测试类形式.py::TestDemo::test_ab PASSED [ 50%]
test_测试类形式.py::TestDemo2::test_a PASSED [ 75%]
测试函数形式_test.py::test_a PASSED [100%]
========================================================= 4 passed, 5 deselected in 0.03s =========================================================
用法二:匹配类名, 指定文件:
pytest -v .\test_测试类形式.py -k "TestDemo", 没有执行TestCase类中的方法
# test_测试类形式.py
import pytest
class TestDemo:
def test_a(self):
print("TestDemo -> test_a")
assert 3 > 2
def test_ab(self):
print("TestDemo -> test_ab")
class TestDemo2:
def test_a(self):
print("TestDemo2 -> test_a")
def test_b(self):
print("TestDemo2 -> test_b")
class TestCase(object):
def test_func1(self):
print('TestCase -> test_func1 run')
测试结果:
PS E:\PyProject\demo\pytest> pytest -v .\test_测试类形式.py -k "TestDemo"
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- E:\PyProject\py_basic\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.1', 'Platform': 'Windows-10-10.0.19042-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins
': {'html': '3.1.1', 'metadata': '1.11.0', 'ordering': '0.6', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'E:\\code_tool\\java\\jdk1.8.0_311'}
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 5 items / 1 deselected / 4 selected
test_测试类形式.py::TestDemo::test_a PASSED [ 25%]
test_测试类形式.py::TestDemo::test_ab PASSED [ 50%]
test_测试类形式.py::TestDemo2::test_a PASSED [ 75%]
test_测试类形式.py::TestDemo2::test_b PASSED [100%]
========================================================= 4 passed, 1 deselected in 0.02s =========================================================
用法三: -k "类名 and not 方法名"
PS E:\PyProject\demo\pytest> pytest -v -k "TestDemo and not test_a" .\test_测试类形式.py
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- E:\PyProject\py_basic\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.1', 'Platform': 'Windows-10-10.0.19042-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins
': {'html': '3.1.1', 'metadata': '1.11.0', 'ordering': '0.6', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'E:\\code_tool\\java\\jdk1.8.0_311'}
rootdir: E:\PyProject\demo\pytest
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 5 items / 4 deselected / 1 selected
test_测试类形式.py::TestDemo2::test_b PASSED [100%]
========================================================= 1 passed, 4 deselected in 0.01s =========================================================
-p no:plugin_name: 不执行相关插件
标记机制
@pytest.mark 标记测试用例,执行的时候用 -m 指定
# test_测试类形式.py
import pytest
class TestDemo:
@pytest.mark.L1
@pytest.mark.L2
def test_a(self):
print("TestDemo -> test_a")
assert 3 > 2
@pytest.mark.L3
def test_ab(self):
print("TestDemo -> test_ab")
class TestDemo2:
@pytest.mark.L1
def test_a(self):
print("TestDemo2 -> test_a")
@pytest.mark.L3
def test_b(self):
print("TestDemo2 -> test_b")
执行:
PS E:\PyProject\demo\pytest> pytest .\test_测试类形式.py -m "L1" -v
=============================================================== test session starts ===============================================================
platform win32 -- Python 3.10.1, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- E:\PyProject\py_basic\Scripts\python.exe
cachedir: .pytest_cache
metadata: {'Python': '3.10.1', 'Platform': 'Windows-10-10.0.19042-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins
': {'html': '3.1.1', 'metadata': '1.11.0', 'ordering': '0.6', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'E:\\code_tool\\java\\jdk1.8.0_311'}
rootdir: E:\PyProject\demo\pytest, configfile: pytest.ini
plugins: html-3.1.1, metadata-1.11.0, ordering-0.6, rerunfailures-10.2
collected 4 items / 2 deselected / 2 selected
test_测试类形式.py::TestDemo2::test_a PASSED [100%]
========================================================= 2 passed, 2 deselected in 0.01s =========================================================
使用标记的时候会有以下警告:
解决办法是在pytest.ini 文件中进行标记注册, 注意第二个标签需要换行和缩进:
[pytest]
markers = L1
L2
L3
-m 结合 not 使用:
-m 结合 or 使用:
-m 结合 not mark and not mark 使用:
执行了非标记test_two方法
全局配置
我们可以在测试目录下新建一个pytest.ini 文件, 文件中可以设定一些执行规则,借助该文件可以修改pytest的默认行为,即执行规则
- 配置文件的名字可以为:
pytest.ini|tox.ini
- 配置文件案例1:
[pytest]
testpaths = case
addopts = -s
python_files = test_*.py
python_classes = Test*
python_functions = test_*
- 配置文件案例2:
[pytest]
testpaths = case
addopts = -s
python_files = demo_*.py
python_classes = Demo*
python_functions = demo_*
自定义配置说明:运行case 路径下 -> demo开头的py文件 -> Demo类 -> demo开头的方法
配置项说明:
- testpaths : 指定路径
- addops: 指定运行pytest的参数
- python_files: 指定要运行的文件
- python_class: 指定测试类
- python_functions: 指定测试方法
使用配置文件后可以快速的使用配置项来选择执行哪些测试模块,需要注意的是:
- 在windows系统下,pytest配置文件不允许写注释
- 在一个工程内只需要一个pytest配置文件
- 一般情况,只需要将配置文件,放在工程跟路径下
- 配置有pytest配置文件的过程,只需要打开命令行,输入pytest指令,即可执行测试
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/15719624.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!