文章目录
-
- pytest是什么?
- 如何安装pytest?
- pytest的基本用法
- pytest的高阶用法
-
- 1.mark
-
- 用户自己的标记
- 框架内置的标记
-
- **`@pytest.mark.parametrize`**:
- **`@pytest.mark.skip`**:
- **`@pytest.mark.skipif`**:
- **`@pytest.mark.xfail`**:
- **`@pytest.mark.usefixtures`**:
- **`@pytest.mark.filterwarnings`**:
- **`@pytest.mark.timeout`**:
- **`@pytest.mark.django_db`**(Django专用):
- **`@pytest.mark.asyncio`**:
- **`@pytest.mark.parametrize`与多个参数化**:
- 2.fixture
- pytest的相关框架封装demo
- pytest和unittest的区别
pytest是什么?
Pytest 概念
Pytest 是 Python 的一种单元测试框架,与 Python 自带的 unittest 测试框架类似,但 Pytest 使用起来更简洁,效率更高。
Pytest 特点
Pytest 是一个非常成熟的 Python 测试框架,主要特点有以下几点:
- 易上手:入门简单,文档丰富,文档中有很多实例可以参考。
- 支持多种测试:能够支持简单的单元测试和复杂的功能测试。
- 参数化:支持参数化测试。
- 跳过测试:在执行测试过程中可以将某些测试用例跳过(skip),或者对某些预期失败的 case 标记成失败。
- 重试失败:支持重复执行 (rerun) 失败的 case。
- 兼容性:支持运行由 nose、unittest 编写的测试 case。
- 报告生成:可生成 HTML 报告。
- 持续集成:方便与 Jenkins 等持续集成工具结合使用。
- 部分用例执行:可支持执行部分用例。
- 插件支持:具有很多第三方插件,并且可以自定义扩展。
如何安装pytest?
安装
pip install pytest
验证安装
pytest --version # 会展示当前已安装版本
pytest官方文档
官方文档:https://docs.pytest.org/en/latest/contents.html
pytest的基本用法
测试用例的规则
- 创建
test_demo.py
开头的文件 - 创建
Test
开头的类 - 创建
test_
开头的函数或者方法
如下:
import pytest
def test_a(): # 函数
pass
class Test(object): # 类
def test_b(self): # 方法
pass
简单的执行用例的命令就是 pytest
,从执行结果中我们可以看到它运行了2条用例,并且全部都测试通过了。
因此我们得出一个结论:
- pytest是以每个函数或者方法作为一个用例的
- pytest主要以名字区分普通函数/方法和用例
- pytest的启动方式就是在命令行输入
pytest
- pytest会自动输出用例情况,执行情况以及汇总情况
测试用例的断言
断言demo
import pytest
def test_a(): # 函数
assert 1 == 1 # 这里会测试通过
class Test(object): # 类
def test_b(self): # 方法
assert 1 == 2 # 这里会测试失败
def test_c(self): # 方法
assert 2 == 2 # 这里会测试通过
当我们用 pytest
运行的时候,我们会得到3个结果。1个失败2个通过。并且失败的用例会以报错的形式展现出来 AssertionError
,但是它不会中断测试。
如下:
读懂测试用例结果
我们通过观察pytest的测试结果,其实每行结果都是有价值的。但是对我们来讲,我们更关心的是中间这行。
pytest代码/test_1.py .F.
这代表着执行用例的情况,是否百分之百完成,并且是否通过。
这里有两个绿点,中间是一个红色的F,这代表着执行了3条用例,并且第一条和最后一条是通过的,中间一条是失败的。
具体解析的表格如下:
缩写 | 单词 | 含义 |
---|---|---|
. | passed | 通过 |
F | failed | 失败(用例执行时的错误) |
E | error | 出错(fixture执行报错) |
s | skipped | 跳过 |
X | xpassed | 预期外的通过 |
x | xfailed | 预期中的失败 |
上面的讲解是为了更好的介绍pytest的用法。但是基础用法知识知道让我们知道了怎么用。但无法运用在真实的测试场景,因此我们自己看下面的高阶用法的讲解。
pytest的运行方式
例如在终端输入命令
#终端输入:pytest ./test_one.py --html=./report/report.html
这就代表着运行pytest的test_one.py
文件,并且输出测试报告
pytest的配置文件
pytest 支持多种配置文件格式,主要包括 pytest.ini、tox.ini 和 setup.cfg。这些文件可以包含不同的配置选项,如下:
pytest.ini
示例
[pytest]
# 指定测试文件的搜索路径
testpaths = tests
# 添加默认的命令行选项
addopts = -v --tb=short
# 设置命令行日志的级别
log_cli_level = INFO
# 定义自定义标记
markers =
slow: mark test as slow
smoke: mark test as smoke
regression: mark test as regression
# 指定测试文件的匹配模式
python_files = test_*.py *_test.py
# 指定测试类的匹配模式
python_classes = Test*
# 指定测试函数的匹配模式
python_functions = test_*
# 指定缓存目录
cache_dir = .pytest_cache
# 禁用警告输出
disable_warnings = true
# 其他配置项可以根据需要添加
tox.ini
示例
[tox]
# 指定要测试的环境列表
envlist = py37, py38, py39
[testenv]
# 在每个环境中安装的依赖
deps = pytest
# 在每个环境中运行的命令
commands = pytest
setup.cfg
示例
[metadata]
name = your_package_name
version = 0.1.0
description = A sample Python package
[options]
packages = find:
[tool:pytest]
# pytest 的配置
testpaths = tests
addopts = -v --tb=short
markers =
slow: mark test as slow
smoke: mark test as smoke
- 将上述配置文件放置在项目根目录下。
- 根据项目的实际需求,我们可以修改相应的配置项。
- 运行
pytest
时,pytest 会自动读取这些配置文件,应用相应的设置。
pytest的高阶用法
1.mark
mark
标记,就是为了让用例跟用例之间都不相同。实现用例的筛选(相当于一个人的身份证号,也代表着用例代号)
用户自己的标记
- 使用标记
我们在刚才的测试用例上添加@pytest.mark.api1
import pytest
@pytest.mark.api
def test_a(): # 函数
assert 1 == 1 # 这里会测试通过
class Test(object): # 类
@pytest.mark.name
def test_b(self): # 方法
assert 1 == 2 # 这里会测试失败
@pytest.mark.age
def test_c(self): # 方法
assert 2 == 2 # 这里会测试通过
- 选择用例
如果我们直接执行pytest
,那么它仍然会全部执行。所以我们想要筛选用例,那么将会用到下面的命令
pytest -m api
那么我们可以看到,他只会执行一条带有api
标签的用例,剩下的是不执行的。另外两个用例属于未执行
的状态
但记住,一个用例可以有多个标记,如下:
import pytest
@pytest.mark.api
@pytest.mark.name
def test_a(): # 函数
assert 1 == 1 # 这里会测试通过
class Test(object): # 类
@pytest.mark.name
def test_b(self): # 方法
assert 1 == 2 # 这里会测试失败
@pytest.mark.age
def test_c(self): # 方法
assert 2 == 2 # 这里会测试通过
当我们执行pytest -m name
的时候,它就会执行两条用例。
框架内置的标记
pytest
提供了多个基于 @pytest.mark
的标记(markers)来控制测试的执行方式。以下是一些常用的标记:
@pytest.mark.parametrize
:
- 用于参数化测试,允许为测试函数提供多个参数集。
@pytest.mark.parametrize("input, expected", [(1, 2), (2, 3), (3, 4)])
def test_addition(input, expected):
assert input + 1 == expected
@pytest.mark.skip
:
- 跳过当前测试,不执行。
@pytest.mark.skip(reason=