按基础到进阶的顺序,学习Python的pytest框架,本篇文章先讲一讲pytest的基本概念、入门使用规则。
目录
一、pytest基础知识
1、安装
2、pytest框架主要做了什么工作
二、pytest的规则约定、运行方式以及参数详解
1、编写测试用例
模块(文件)命名规则:
测试类命名规则:
测试方法命名规则:
使用assert进行断言:
2、运行测试
命令行模式
主函数模式
pytest.ini配置文件
测试失败时的输出解读
(1). 测试结果概览
(2).失败测试详细信息
(3).回溯(Traceback)
一、pytest基础知识
pytest是一个基于Python语言的单元测试框架,它可以和selenium、requests、appium结合实现web、接口、app自动化测试,它可以通过结合各种第三方库来实现自动化测试和其他工作,关于pytest框架系列的文章我们主要就pytest进行学习讨论。
1、安装
步骤:命令行环境确保已安装Python并配置好环境变量,通过pip安装:
pip install pytest
#如果已安装旧版本
pip install --upgrade pytest #可升级至最新版本pytest
在pycharm集成环境中,可以在terminal终端命令框中输入同上指令安装
pytest有很多强大的插件:
- pytest-html 生成html报告
- pytest-xdist 多线程
- pytest-ordering 控制测试用例执行顺序
- pytest-rerunfailures 失败用例重跑
- pytest-base-url 基础路径
- allure-pytest 生成allure报告
我们可以通过一个requirements.txt文件保存这些插件和第三方库,一次性安装
pip install -r requirements.txt
验证安装,在命令行环境输入:
pytest --version
如输出版本号,即验证安装成功
2、pytest框架主要做了什么工作
(1)、自动发现并执行测试用例
(2)、利用断言语句判断测试结果,断言失败时,pytest会输出清晰的错误消息,包括表达式、预期值、实际值以及上下文信息
(3)、生成测试报告
pytest框架能做的工作还能细分很多,在此不一一例举,我们先了解大致
二、pytest的规则约定、运行方式以及参数详解
1、编写测试用例
pytest通过特定的文件名和函数名约定来自动发现测试用例。对于测试用例函数,其名称应遵循以下规则:
模块(文件)命名规则:
文件名:测试模块(即Python源文件)应遵循以下命名规则之一:
以 test_ 开头,如 test_math.py。
以 _test.py 结尾,如 math_test.py。
通过这样的命名,pytest能在自动发现测试时识别出这些文件包含了测试代码。
测试类命名规则:
类名:测试类的名称应以字符串 "Test" 作为前缀。例如:
class TestMathFunctions:
...
类名应具有描述性,反映所包含测试方法所属的功能或模块。遵循这一命名约定的类会被pytest视为测试集合类,其中的方法会被当作独立的测试用例来执行。
测试方法命名规则:
方法名:测试方法(即测试用例)应以字符串 "test_" 作为前缀。例如:
def test_addition():
...
方法名应具体描述被测试的功能或场景,以便于快速理解测试的目的。pytest会自动识别并执行以 test_ 开头的函数作为测试用例。
注意事项:
避免定义 __init__ 方法:在测试类中,通常不应定义 __init__ 构造方法。pytest在实例化测试类时并不期望它们具有自定义的初始化逻辑。如果需要执行与类相关的初始化操作,可以使用类级别的setup/teardown方法(如setup_class 和 teardown_class)。
方法可见性:测试方法应为公有(def test_something():)或受保护(def test_something(self):),不推荐使用私有方法(def _test_something(self):),因为私有方法不会被pytest自动发现。
方法顺序:pytest在类内执行测试方法的顺序通常是按照方法在类中定义的顺序进行,而非方法名排序。
遵循上述命名规则,pytest能够有效地识别并组织项目的测试用例,简化测试执行过程,确保测试自动化工作的顺利进行。在实践中,除了这些基本命名规则外,还应注意保持测试代码的整洁与可读性,以及合理利用pytest提供的fixture、参数化测试等功能来提高测试的效率与覆盖率。
使用assert进行断言:
在测试用例中,通过assert
语句来设置预期结果与实际结果之间的比较。当断言条件为真时,测试通过;否则,测试失败,并抛出AssertionError
。典型的pytest测试用例可能包含如下结构:
from my_module import Calculator #导入待测试模块、类
def test_addition(): #测试方法
calculator = Calculator() #实例化待测试类
result = calculator.add(2, 3) #测试结果
assert result == 5, f"结果应该等于5,但是输出结果为:{result}" #断言测试结果,如果断言失败,抛出自定义异常
2、运行测试
命令行模式
用户可以直接在终端或命令提示符中输入 pytest 命令来运行测试。可以通过指定不同的参数和选项来控制测试的执行,如指定测试文件、目录、筛选特定测试、设定输出详细程度等。例如:
pytest #运行当前目录及其子目录下的所有测试。
pytest path/to/test_file.py #运行指定文件中的测试。
pytest path/to/test_directory #运行指定目录下的所有测试。
pytest path/to/test_file.py::TestDemo # 执行到对应模块下的类
pytest path/to/test_file.py::TestDemo::test_add # 执行到对应模块下的类里的方法
pytest -v 或 pytest --verbose #以详细模式运行,提供更丰富的输出信息。
pytest -k keyword #仅运行包含指定关键字的测试。
pytest -m marker #仅运行标记为特定标记(marker)的测试。
#更多参数和选项可以通过 pytest --help 查看。
主函数模式
在 Python 脚本中直接调用 pytest.main() 函数来运行测试。这种方式允许在程序中嵌入pytest的执行,便于集成到其他自动化流程或者脚本中。可以传入参数列表来定制测试执行行为,如:
import pytest
if __name__ == '__main__':
pytest.main() #运行默认设置下的所有测试。
pytest.main(['-vs', 'test_login.py']) #以详细和显示打印信息模式运行指定文件的测试。
pytest.main(['-vs', './in_testcase']) #以同样详细模式运行指定目录下的所有测试。
pytest.main(['-vs', './in_testcase/test_interface.py::test_04_func']) #运行指定文件内特定函数的测试。
pytest.main(['-vs', './in_testcase/test_interface.py::Testinterface::test_03_zhiliao']) #运行指定文件内特定类和方法的测试。
pytest.ini配置文件
创建一个名为 pytest.ini 的配置文件,放置在项目根目录下。在这个文件中可以定义默认的命令行选项、测试收集规则、插件设置等。例如:
[pytest]
#配置运行时参数
addopts = -vs -m "user or smoke"
#配置发现测试用例的位置
testpaths = ./testcases
#配置并修改发现模块的默认规则
python_files = test_*.py
#配置并修改发现类的默认规则
python_classes = Test*
#配置并修改发现用例的默认规则
python_functions = test_*
#标记用例(冒烟测试,分模块运行测试用例,接口和web分离)
markers =
smoke:冒烟测试
user:用户管理模块
参数列表:
-v 输出详细信息-s 输出调试信息
-n 多线程运行 可以减少运行时间
--reruns=x 失败用例重跑 一条用例可以失败重跑x次 自定义次数
-x 用例出现1个失败就停止测试
--maxfail=x 用例出现x个失败就停止测试
--html=路径 生成html报告 路径规则 要使用”/” 如../python_autotest_study/practice/reports.html 结尾要有文件名,可以使用相对路径 ./reports.html 生成在当前目录
-k=XX 运行名称中包含有特定字符串XX的测试用例
-m 用于执行特定标记的用例:-m "smoke or user"
运行测试时,pytest会自动读取并应用这些配置,无需在命令行中显式指定,pytest.ini配置文件只是配置全局,执行还是需要在命令行或者主函数模式执行。
运行模式总结
命令行模式适合日常手动执行和CI/CD环境中的自动化测试,主函数模式适用于在Python脚本中嵌入pytest执行,而配置文件则方便对整个项目的测试行为进行统一管理和持久化配置。
测试失败时的输出解读
当pytest测试失败时,其输出包含丰富的信息,帮助开发者快速定位和理解失败原因。以下是pytest测试失败时输出的解读:
(1). 测试结果概览
首先,pytest会显示一个简要的测试结果概览,通常包含以下内容:
- 总测试数:执行的测试用例总数。
- 通过数:成功通过的测试用例数量。
- 失败数:导致失败的测试用例数量。
- 跳过数(如果使用):被跳过的测试用例数量,可能由于标记(markers)或条件判断(如pytest.mark.skip、pytest.mark.skipif)导致。
- 错误数(如果使用):测试执行过程中出现非预期错误(如代码异常)的测试用例数量。
- 测试执行时间:整个测试套件的运行时间。
(2).失败测试详细信息
对于每个失败的测试,pytest会输出详细的错误信息,包括:
- 测试路径:失败测试所在的文件名和行号,以及完整的测试函数签名(包括类名,如果有)。
- 失败原因:AssertionError消息,通常包含断言失败的具体条件和实际值。如果使用了自定义的错误消息,也会在此处显示。
- 堆栈跟踪:从失败点向上追溯的函数调用序列,直至测试函数的入口。堆栈跟踪有助于找到导致失败的代码行和上下文。如果测试失败涉及多个断言,pytest可能会为每个失败断言分别提供上述信息。
(3).回溯(Traceback)
紧随错误消息之后,pytest会显示一个详细的回溯(traceback),即从失败点开始向上遍历的函数调用链,直到引发错误的源头。每一层回溯包括:
- 文件名:发生错误的Python源文件。
- 行号:错误发生的代码行。
- 函数/方法名:引发错误的函数或方法名称。
- 源代码片段:错误发生位置的上下文代码行。
回溯信息有助于快速定位到导致失败的具体代码行,以及理解错误发生时的调用关系。
希望该篇文章能帮助到大家快速了解pytest的基础内容,知晓pytest的模块、类、方法命名约定,以及它的各种运行模式和统一管理配置,以便后续我们继续深入学习pytest框架~