1、pytest基础
【资料地址】
【安装】
pip install pytest
pip install pytest -u
pip install pytest==9.0
参数解释:
pip install 安装第三方库的命令
pytest 第三方库的名字
-u 升级到最新版本
==9.0 指定版本号
【检查安装】
pytest --version
where pytest
pip show pytest
参数解释:
pytest --version 查看安装版本
where pytest 查看安装的目录
pip show pytest 查看安装的pytest详细信息
【pytest用例发现规则】
pytest识别、加载测试用例过程称之为:"用例发现规则",具体规则:
1.遍历所有的目录,venv除外;(v:虚拟,env:环境)
2.遍历所有test_开头或者_test结尾的python文件
3.遍历所有Test开头的类
这些类不能拥有__init__方法
4.搜集test_开头的函数或者方法,作为测试用例
重点:pytest只有函数和方法才能被视为测试用例,目录、文件、类,作为用例的容器
【配置pytest】
查看配置项:
pytest -h
常用的参数:
-v 增加详细程度
-q 减少详细程度
-s 正常执行也显示打印内容,进入输入(不进行内容捕获)
-x 当遇到失败就退出
根据执行2选一来的配置(选2的直接看2):
1、命令行配置
pytest -q test_tmp_path.py
2、文件配置pytest.ini
1.在根目录创建pytest.ini
2.创建pytest选择器[pytest]
3.按行,添加配置项addopts=
[pytest]
addopts = -q test_tmp_path.py
【执行pytest】
执行2选一(建议选2)
1.命令行执行
pytest
2.文件执行 run.py
import pytest
pytest.main() # 启动测试框架
【用例栗子】
def func(x):
return x + 1
def test_passed1():
assert func(1) == 2
def test_failed():
assert func(3) == 5
def test_passed2():
print("*"*30)
print("func(1) == 2")
print("*"*30)
assert func(1) == 2
assert是断言
【查看执行结果】
| 缩写 | 单词 | 含义 |
| . | passed | 通过 |
| F | failed | 失败(用例执行时报错) |
| E | error | 出错(fixture执行报错) |
| s | skipped | 跳过 |
| X | xpassed | 预期外的通过(不符合预期) |
| x | xfailed | 预期内的失败(符合预期) |
2、pytest的扩展知识
【mark标记】
1、用户自定义标记(需要注册)
不注册,即使运行筛选了,也会全执行(addopts增加--strict可以直接报错不执行),还会警告
You can register custom marks to avoid this warning - for details, see巴拉巴拉
注册:marks = 自定义标记
(标记名称后 : 之后的任何内容都是可选描述)
使用:-m 自定义标记
(支持逻辑运算,要是写了逻辑运算别忘记引号,例如:-m "mark1 or mark2",不用引号逻辑运算符会被当做未注册的标签)
栗子:
在pytest.ini中添加
[pytest]
addopts= -m mark1 --strict
markers =
mark1:"mark1的说明说明说明"
mark2
mark3
另外还有2种注册方式:
在pyproject.toml中添加(补充知识:pyproject.toml是一种用于描述项目配置的文件格式,它定义了项目的元数据和依赖项。)
[tool.pytest.ini_options]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"serial",
]
在 pytest_configure 钩子中以编程方式注册新标记
def pytest_configure(config):
config.addinivalue_line(
"markers", "env(name): mark test to run only on named environment"
)
2、框架内置标记(不需要注册)
skip - 始终跳过测试函数
skipif - 如果满足某个条件,则跳过测试函数
xfail - 如果满足某个条件,则产生“预期失败”结果
import pytest
# 跳过
@pytest.mark.skip()
def test_ok():
assert 1 == 1
# 跳过
@pytest.mark.skipif(1 == 1, reason="有条件跳过")
def test_fail():
assert 1 == 2
class Test:
# 预期外通过Xpass
@pytest.mark.xfail # 预期失败
def test_class_ok(self):
print("我是test_class_ok")
assert 1 == 1
# 预期外失败Xfail
@pytest.mark.xfail # 预期失败
def test_class_fail(self):
print("我是test_class_fail")
assert 1 == 2
parametrize - 对同一个测试函数执行多次调用
import pytest
def add(a, b):
return a + b
@pytest.mark.parametrize(
"a,b,c",
[
[1, 1, 2],
[2, 2, 4],
[2, 3, 5],
[3, 3, 6],
]
)
def test_add_n_m(a, c, b):
assert add(a, b) == c
usefixtures - 在测试函数或类上使用固定装置
有@pytest.fixture且是个函数就是fixture,里面用yield来分割执行前执行后
import pytest
@pytest.fixture
def f():
print("启动浏览器") # 前置操作,用例执行之前,自动执行
yield "浏览器类型:chrome" # 返回值,供用例使用
print("关闭浏览器") # 后置操作,用例执行之后,自动执行
def test_abc(f): # 标准使用fixture,可以拿到返回值
print("我是用例内容,正在执行")
print("收到了fixture的返回值", f)
@pytest.mark.usefixtures("f")
def test_abc1(): # 使用fixture
print("我是用例内容,正在执行")
pfilterwarnings - 过滤测试函数的某些警告
【夹具fixture】
在测试中,fixture 为测试提供了一个已定义的、可靠的和一致的上下文。
测试也不必局限于单个 fixture。它们可以依赖于任意数量的 fixture,而 fixture 也可以使用其他 fixture。
import pytest
class Fruit:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
@pytest.fixture
def my_fruit():
print(f'my_fruit:{Fruit("apple").name}')
return Fruit("apple")
@pytest.fixture
def fruit_basket(my_fruit):
print(f'fruit_basket:{Fruit("banana").name}, {my_fruit.name}')
return [Fruit("banana"), my_fruit]
def test_my_fruit_in_basket(my_fruit, fruit_basket):
print("test_my_fruit_in_basket")
assert my_fruit in fruit_basket
【测试配置conftest.py】
conftest.py 被pytest自动导入,实现跨文件的fixture,每个目录都可以创建一个该文件(优先级:就近原则)。
import pytest
@pytest.fixture(scope='package')
def f():
print("启动浏览器bbb") # 前置操作,用例执行之前,自动执行
yield "浏览器类型:chrome" # 返回值,供用例使用
print("关闭浏览器bbb") # 后置操作,用例执行之后,自动执行
fixture的作用域,一共5级,设置语法:@pytest.fixture(scope='作用域')
1、funcation 默认,不共享
2、class 同一个类里面共享
3、module 同一个模块(文件)里面共享
4、package 同一个包(目录)里面共享
5、session 全局共享

被折叠的 条评论
为什么被折叠?



