文章目录
-
-
- [Pytest 简介](#Pytest 简介)
- [Pytest 官网](#Pytest 官网)
- [Pytest 核心](#Pytest 核心)
- [Pytest 原理](#Pytest 原理)
- [Pytest 用途](#Pytest 用途)
- [Pytest 特点](#Pytest 特点)
- [Pytest 安装](#Pytest 安装)
- [Pytest 编写测试用例规则](#Pytest 编写测试用例规则)
- [Pytest 编写第一条测试用例](#Pytest 编写第一条测试用例)
- [Pytest 运行方式](#Pytest 运行方式)
- Pytest.main()常用命令
-
Pytest 简介
Pytest是一个功能强大的Python测试框架,它简化了测试编写的复杂性,并提供了丰富的插件生态系统,以满足各种复杂的测试需求。
与Python内置的
unittest
框架相比,Pytest
的语法更简洁、更易于理解,支持参数化测试、测试固件(fixtures)、断言重写等高级功能。此外,Pytest还允许用户通过插件来扩展其功能,从而更好地适应各种项目规模和要求。
无论是在小型项目中进行简单的单元测试,还是在大型项目中进行复杂的集成测试和功能测试,
Pytest
都能够提供强大的支持。它支持并发执行测试用例,可以方便地选择执行特定的测试用例集,并且提供了详细的测试报告和日志输出,帮助开发者快速定位和修复问题。
此外,
Pytest
还与其他流行的Python工具和库(如Selenium、Django等)无缝集成,使得自动化测试变得更加容易和高效。
Pytest 官网
Pytest 核心
Pytest测试框架的核心是Fixture和Mark
Fixture:
- Fixture是Pytest中的一个重要概念,它允许在测试用例执行前后设置和清理测试环境;
- 可以将Fixture看作是一些预定义的、可重复使用的配置或资源,这些配置或资源可以在多个测试用例之间共享;
- 通过使用fixture,可以更加灵活和高效地管理测试依赖和测试环境。
Mark:
- Mark是Pytest提供的一种装饰器,用于对测试用例或fixture进行标记;
这些标记可以用来控制测试用例的执行方式,例如跳过某些测试、指定测试的执行顺序等。
Mark
提供了一种灵活的方式来管理和控制测试用例的行为。
Pytest 原理
- 测试自动发现 :
Pytest
会自动查找和收集符合特定模式的测试文件和函数,这意味着无需手动指定要运行的测试。- 多种类型的测试 :
Pytest
支持多种类型的测试,包括单元测试、集成测试、端到端测试等,这使得它适用于不同规模和复杂度的项目。- Fixture机制 :如前所述,
Fixture
机制允许定义和重用测试环境配置,使得测试编写更加灵活和高效。- 参数化测试 :
Pytest
支持参数化测试,这意味着可以使用不同的输入参数多次运行相同的测试代码,从而增加测试覆盖率和效率。- 丰富的插件机制 :
Pytest
具有强大的插件生态系统,这些插件可以提供各种额外功能,如覆盖率分析、测试报告生成等,使得测试过程更加全面和高效。- 多种执行方式 :
Pytest
支持多种执行方式,包括命令行执行、配置文件执行和插件执行等,这使得测试的执行方式非常灵活,可以根据项目需求进行定制。
Pytest 用途
Pytest的应用场景包括但不限于以下几个方面:
- 单元测试:对程序的一个小部分或一个函数进行测试,看它是否按照预期进行工作。
- 功能测试:确保软件的某个功能是否工作正常。
- 回归测试:当代码有所改动时,pytest可以帮助确认改动部分是否运行良好,并且改动没有影响到其他部分的功能。
- 集成测试:当想同时测试两个或多个组件的集成程度时,pytest可以提供强大的支持。
测试人员 :可以使用
Pytest
来编写和执行测试用例,验证软件的功能和性能是否满足要求,并生成详细的测试报告和日志,帮助开发团队快速定位和修复问题。开发人员 :可以使用
Pytest
来编写单元测试,确保代码的各个单元功能正常,并在代码改动时进行回归测试,以确保改动没有引入新的问题。
Pytest 特点
- 易于使用和上手 :
pytest
具有与unittest
相似的结构,使得测试人员能够轻松地从unittest
迁移到pytest
,同时保持测试的连续性和一致性。其简洁的语法和直观的测试结构使得入门变得简单快捷。- 强大的Fixture机制 :
pytest
的Fixture
提供了一种灵活的方式来管理和控制测试环境的设置和清理。它支持在测试用例执行前后进行各种资源的配置和共享,使得测试编写更加高效和可维护。- 参数化测试 :
pytest
允许通过parametrize
装饰器对测试用例进行参数化,这意味着可以使用不同的输入参数多次运行相同的测试用例,从而增加测试的覆盖率和可靠性。- 灵活的测试控制 :
pytest
提供了skip
和xfail
装饰器,允许测试人员在测试执行过程中跳过某些测试用例或标记预期失败的测试用例。这对于处理不稳定或依赖外部资源的测试非常有用。- 失败重试机制 :
pytest
支持通过插件(如pytest-rerunfailures)实现失败测试用例的自动重试,从而提高测试的可靠性和稳定性。- 广泛的兼容性 :
pytest
能够执行由nose
和unittest
编写的测试用例,这使得它能够轻松集成现有的测试代码库,并充分利用pytest
的强大功能。- 选择性执行测试用例 :
pytest
允许测试人员根据标记、文件名或其他条件选择性地执行特定的测试用例,从而更加灵活地控制测试的执行范围。- 丰富的插件生态系统 :
pytest
拥有一个庞大的插件生态系统,提供了许多额外的功能和工具,如测试报告生成、并行执行、测试顺序控制等。这些插件可以通过简单的安装和配置来扩展pytest
的功能。- 精美的测试报告 :
pytest
可以生成简洁明了的HTML测试报告
,帮助测试人员快速了解测试的执行情况和结果。此外,结合Allure
等第三方插件,还可以生成更加精美和详细的测试报告。- 与持续集成工具的无缝集成 :
pytest
可以轻松地与持续集成工具(如Jenkins)集成,实现自动化构建、测试和报告生成。这使得测试流程更加高效和可靠,有助于提高软件的质量和交付速度。
Pytest 安装
pytest
属于python的第三方库,需要额外下载安装,命令如下:
python
pip install pytest
Pytest 编写测试用例规则
模块 (Modules)
- 文件名约定 :
pytest
会自动发现以test_
开头或以\_test
结尾的Python文件并执行其中的测试。推荐的做法是使用test_
前缀加上业务名称来命名测试文件,例如test_my_feature.py
。类 (Classes)
- 类名约定 :测试类应该以
Test
开头,并且不应包含\__init__
方法。\__init__
方法通常用于类的初始化,但在测试类中不需要它,因为它会干扰pytest
对测试方法的识别。方法/函数 (Methods/Functions)
- 方法名约定 :测试方法或函数应该以
test_
开头。pytest
会自动识别并运行所有符合此命名约定的方法或函数。包 (Packages)
- 包名约定 :对于包名,没有特定的约定。但是,每个包都应该包含一个
\__init__.py
文件,即使它是空的。这个文件告诉Python
该目录应被视为一个包,这对于pytest
发现和执行测试非常重要。补充说明:
- 测试结构:除了上述规则外,建议将相关的测试文件组织在同一个目录下,或者使用包来组织具有相似功能的测试。这有助于保持测试代码的清晰和可维护。
- 测试独立性:每个测试方法都应该独立运行,不依赖于其他测试的执行顺序。这有助于确保测试的可靠性和可重复性。
- 断言:测试方法中应该包含断言语句来验证被测试代码的行为是否符合预期。断言是测试的核心,它们确保代码按照预期工作。
Pytest 编写第一条测试用例
用例代码示例
test_case_01.py
文件代码
python
import pytest
def addition(x, y):
return x + y
def test_01_a():
print("正在执行 test_a 函数...")
assert addition(3, 5) == 8
class TestClassCase01:
def test_01_b(self):
assert "a" in "apple"
def test_01_c(self):
assert "a" in "apple"
if __name__ == '__main__':
pytest.main()
test_case_02.py
文件代码
python
class TestCase01:
def test_02_a(self):
print("正在执行 test_02_a 函数...")
def test_02_b(self):
print("正在执行 test_02_b 函数...")
可执行测试
执行一条测试
点击
任意
测试用例函数的绿色按钮,用pytest
解释器执行,而不是python解释器执行
执行多条测试
点击
main
函数的绿色按钮,或者直接右键选择pytest
解释器执行
Pytest 运行方式
run模式
通过Pyton解释器来执行
test_case_01.py
文件;注意 :文件中带有
main
函数重点 :
pytest.main()
等价于pytest.main(["./"])
会收集当前目录下的所有用例并执行
test_case_01.py
文件中没有main
函数
pytest模式
通过pytest程序执行
test_case_01.py
文件
run模式扩展
- 运行所有
pytest.main()
- 运行指定模块
pytest.main('[-vs],','./test_case_01.py')
- 运行指定目录
pytest.main('[-vs]'),'./')
- 通过nodeid指定用例运行:nodeid由模块名,分隔符,类名,方法名,函数名组成
执行某个类:
pytest.main(["-vs"],'./test_case_01.py::TestClassCase01')
执行某个方法:
pytest.main(["-vs"],'./test_case_01.py::TestClassTest01::test_01_b')
执行模块中某个方法:
pytest.main(["-vs"],'./test_case_01.py::test_01_a')
命令行模式
基本运行命令:
pytest
:运行当前目录及其子目录中所有符合测试文件命名约定的测试。选择测试:
pytest test_case.py
:运行指定的测试模块。pytest test_directory/
:运行指定目录下的所有测试。pytest -k "expression"
:根据表达式选择测试名称匹配的测试。pytest -m "marker"
:根据标记选择测试。控制运行:
pytest -x
或--maxfail=num
:在遇到第一个失败的测试时停止。pytest --lf
或--last-failed
:仅重新运行上次失败的测试。pytest -n NUM
或--numprocesses=NUM
:使用多进程运行测试。pytest --failed-first
:先运行上次失败的测试。
Pytest.main()常用命令
指定测试文件或用例:
- 文件名/文件路径:直接指定要运行的测试文件、相对路径或绝对路径。
- 测试文件::测试类:指定要运行的测试类。
- 测试文件::测试类::测试用例:指定要运行的特定测试用例。
通用选项:
- -v, --verbose:增加输出的详细程度。
- -q, --quiet:减少输出的详细程度,只报告测试结果。
- -x, --exitfirst:在第一个失败的测试后停止执行。
- -k 表达式:根据表达式选择性地运行测试。
- -m 标记:只运行带有指定标记的测试。
- -s :禁用所有输出捕获,包括
控制输出和日志:
- --durations=N:显示最慢的N个测试用例的执行时间。
- --showlocals:在失败的断言处显示局部变量。
- --tb=风格 :设置失败的回溯打印风格,如
auto
,short
,long
,native
,no
,only_failed
。- --junitxml=path:生成JUnit-XML格式的测试报告。
- --log-cli=true/false:在控制台打印日志。
- --log-cli-level=级别:设置控制台日志的级别。
- --log-cli-format=格式:设置控制台日志的格式。
- --log-cli-date-format=格式:设置控制台日志日期的格式。
- --log-file=path:将日志写入文件。
- --log-file-level=级别:设置文件日志的级别。
- --log-file-format=格式:设置文件日志的格式。
- --log-file-date-format=格式:设置文件日志日期的格式。
控制执行流程:
- --maxfail=num:在达到指定数量的失败测试后停止执行。
- --reruns=n:失败的测试用例重新运行n次。
- --ff:在发现测试之前排序文件。
- --pdb:在失败的测试后启动pdb调试器。
- --looponfail:在失败的测试后无限循环,直到通过。
控制失败的行为:
- --strict:在收集阶段遇到错误时,抛出异常。
- --ignore=path:忽略指定路径下的文件或目录。
- --confcutdir=path:在指定路径以上不加载任何配置文件。