自动化测试基础——Pytest测试框架
Pytest是一个成熟的全功能的Python测试工具Pytest是一个成熟的全功能的Python测试工具简单灵活易上手支持参数化支持简单的单元测试和复杂的功能测试,还可以用来做自动化测试具有很多第三方插件,并且可以自定义扩展测试用例的skip和xfail处理可以很好的和Jenkins集成支持运行由Nose、UnitTest编写的测试用例pytest主要做什么1.执行测试用例2.通过断言判断测试结果
文章目录
- 前言
- 一、Pytest测试框架介绍
- 二、Pytest测试框架安装及常用插件
- 三、Pytest测试框架默认规则
- 四、Pytest测试框架运行方式
- 五、Pytest测试框架中的pytest.ini全局配置文件
- 六、使用Pytest测试框架编写用例
- 七、Pytest跳过测试用例
- 八、Pytest测试用例的前后置
- 九、Pytest测试用例的前后置固件Fixture(固件,夹具)
- 十、Pytest测试用例的前后置固件Fixture结合conftest.py文件一起使用
- 十一、Pytest测试框架的执行过程
- 十二、Pytest测试框架控制测试用例的执行顺序
- 十三、Pytest测试框架的基础路径设置
- 十四、Pytest测试框架断言
- 十五、Pytest测试框架的parametrize简单数据驱动
前言
Pytest是一个成熟的全功能的Python测试工具
一、Pytest测试框架介绍
Pytest是一个成熟的全功能的Python测试工具
-
简单灵活易上手
-
支持参数化
-
支持简单的单元测试和复杂的功能测试,还可以用来做自动化测试
-
具有很多第三方插件,并且可以自定义扩展
-
测试用例的skip和xfail处理
-
可以很好的和Jenkins集成
-
支持运行由Nose、UnitTest编写的测试用例
-
pytest主要做什么
- 1.执行测试用例
- 2.通过断言判断测试结果
- 3.生成测试报告
二、Pytest测试框架安装及常用插件
1.Pytest框架独立安装
-
Pytest框架安装
pip install pytest
-
查看Pytest安装版本
pytest --version
2.通过.txt文件批量安装
-
requirements.txt
文件:用于存放需要安装的第三方库的名称
(requirements.txt文件名可以自定义) -
安装
requirements.txt
文件内指定的第三方库:pip install -r requirements.txt
3.Pytest常用的插件
有的插件,安装之后,自动启用。有的插件,安装之后,配置后才启用
pytest
:pytest测试框架本身pytest-html
:生成html报告(–html 参数的使用)pytest-xdist
:多线程,并发执行用例,并发意味着无序(-n 参数的使用需要用到此插件)pytest-ordering
:控制用例的执行顺序(与pytest-order
插件效果一致)pytest-order
:控制用例的执行顺序(与pytest-ordering
插件效果一致)pytest-rerunfailures
:失败用例重跑(–reruns 参数的使用需要用到此插件)pytest-base-url
:处理基础路径(测试环境、开发环境、预发布环境、生产环境)pytest-result-log
:将用例的名称和结果,保存到日志文件allure-pytest
:生成allure报告requests
:requests是一个简洁且简单的处理HTTP请求的第三方库(实现接口自动化)
pytest-yaml-sanmu
pyyaml
jsonpath
三、Pytest测试框架默认规则
- 会遍历所有的目录(特殊目录除外,比如
venv
文件) - 寻找
test_
开头或_test
结尾的python
文件 - 寻找
Test
开头并且没有__init__
方法的类,从类中按照函数的要求寻找方法
- 寻找
test
开头的函数(1.不能有参数 2.不能拥有返回值)
四、Pytest测试框架运行方式
1.命令行运行
-
命令行使用
pytest
运行pytest
2.主函数运行
-
项目根目录下任意创建一个python文件,编写如下代码,然后运行
import pytest if __name__ == '__main__': pytest.main()
3.通过pytest.ini全局配置文件运行
查看本文的第五大标题
(最常用,也是用的最多的)
4.启动参数
五、Pytest测试框架中的pytest.ini全局配置文件
-
1.
pytest.ini
是Pytest的全局配置文件,一般放在项目的根目录下 -
2.是一个固定的文件,文件名必须为
pytest.ini
-
3.
pytest.ini
全局配置文件可以改变Pytest的运行方式,设置配置信息,读取后按照配置的内容去运行 -
pytest.ini
全局配置文件常用内容如下# pytest.ini是pytest框架的一个全局配置文件 # [pytest]必须带有 [pytest] # addopts:默认执行pytest参数设置 # -v:用于显示每个测试函数的执行结果 # -s:用于显示测试函数中print()函数输出 # -x:只要有一个用例执行失败就停止当前线程的测试执行 # -k=value:用例包含value值则用例被执行(value可以修改为任意值) # -n=2:多线程或分布式运行测试用例,2个线程执行测试用例,减少测试用例执行的时间 # -m=smoke:执行被 @pytest.mark.smoke 标记的用例 # --maxfail=2:有两个用例执行失败就停止当前线程的测试执行 # --reruns=2:失败用例重跑2次 # --html=path:生成HTML测试报告,path代表生成报告存放文件的路径 # addopts = -vsx -n=2 -k=login -m=smoke --maxfail=2 addopts = -vs --html=./report/report.html # 执行的测试用例的的路径 testpaths = ./testcase # 配置匹配执行的文件名称 python_files = test_*.py # 配置匹配类名称 python_classes = Test* # 配置匹配测试用例方法的规则 python_functions = test_* # 声明标记 markers = smoke:冒烟测试用例 usermanager:用户管理模块 productmanager:商品管理模块
参数 | 作用 |
---|---|
-v | (verbose)显示详细信息:执行的用例、结果、进度、用例个数、执行时间 |
-s | 用于显示测试函数中print()函数输出 |
-n=num | 启用多线程或分布式运行测试用例。需要安装 pytest-xdist 插件模块(num代表开启的线程数) |
–reruns=num | 失败用例重跑num次。需要安装 pytest-rerunfailures 插件模块。 |
-x | 只要有一个用例执行失败就停止当前线程的测试执行 |
–maxfail=num | 只要有num个用例执行失败就停止当前线程的测试执行,与-x功能一样,只是用例失败次数可自定义(–maxfail=2) |
-k=value | 用例包含value值则用例被执行(-k=login,执行包含有login的用例,-k=login or register) |
-m=标签名 | 执行被 @pytest.mark.标签名 标记的用例 (-m=smoke or usermanager) |
–reruns=num | 失败用例重跑num次,需要安装 pytest-rerunfailures 插件模块 |
–html=path | 生成HTML测试报告,path代表生成报告存放的路径,需要安装 pytest-html 插件模块(--html=./report/report.html) |
-m
参数的使用
六、使用Pytest测试框架编写用例
- pytest默认规则
- 1.模块名必须以
test_
开头或_test
结尾的python
文件 - 2.测试类必须以
Test
开头并且没有__init__
方法 - 3.测试用例方法必须以
test
开头
- 1.模块名必须以
七、Pytest跳过测试用例
-
无条件跳过
@pytest.mark.skip(reason="无条件直接跳过") def test_add(self): print("这是添加数据用例")
-
有条件跳过
age = 17 @pytest.mark.skipif(age < 18, reason="年龄小于18跳过") def test_register(self): print("这是注册测试用例")
八、Pytest测试用例的前后置
一般现在下面的方法使用的都比较少,一般都是使用Fixture实现
1.用例前后置
-
setup_method
:前置-用例执行之前 -
teardown_method
:后置-用例执行之后# 前置-用例执行之前 def setup_method(self): print("用例之前执行的代码") # 后置-用例执行之后 def teardown_method(self): print("用例之后执行的代码")
注意
:随着Pytest的版本更新可能会无法使用,这里使用的是Pytest 7.4.4 版本进行演示的
2.类前后置
-
setup_class
:类之前 -
teardown_class
:类之后# 类之前 def setup_class(self): print("类之前执行") # 类之后 def teardown_class(self): print("类之后执行")
注意
:随着Pytest的版本更新可能会无法使用,这里使用的是Pytest 7.4.4 版本进行演示的
九、Pytest测试用例的前后置固件Fixture(固件,夹具)
1.Fixture装饰器
@pytest.fixture(scope="作用范围", autouse=True/False,params="参数化",ids="参数别名",name="Fixture别名")
scope
:作用域(function、class、module、package、session)autouse
:自动还是手动(True代表自动,False代表手动)params
:参数化ids
:参数化别名(不重要,不能单独使用,必须和params
一起使用,因为它的作用是参数别名)name
:Fixture别名(一旦使用别名,则原来的名称不能再使用了)
2.Fixture的作用范围
Fixture支持5级作用域,让用例共享Fixture
function
:每个用例不共享Fixture的返回值,默认class
:每个类中的用例,共享Fixturemodule
:每个模块(文件)中的用例,共享Fixturepackage
:每个包(目录)中的用例,共享Fixturesession
:所有的用例,共享Fixture
3.Fixture的使用
-
函数自动调用
import pytest # autouse=True代表自动调用,autouse=False代表手动调用 @pytest.fixture(scope="function", autouse=True) def connection_sql(): print("用例执行前连接数据库") yield print("用例执行后关闭数据库") class TestFirstClass(): def test_login(self): print("这是登陆测试用例") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例")
-
函数手动调用
import pytest # autouse=True代表自动调用,autouse=False代表手动调用 @pytest.fixture(scope="function", autouse=False) def connection_sql(): print("用例执行前连接数据库") yield print("用例执行后关闭数据库") class TestFirstClass(): def test_login(self, connection_sql): print("这是登陆测试用例") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例")
-
类自动调用
import pytest @pytest.fixture(scope="class", autouse=True) def connection_sql(): print("用例执行前连接数据库") yield print("用例执行后关闭数据库") class TestFirstClass1(): def test_login(self): print("这是登陆测试用例") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例") class TestFirstClass2(): def test_delete(self): print("这是删除测试用例") def test_update(self): print("这是修改测试用例")
-
类手动调用
import pytest @pytest.fixture(scope="class", autouse=False) def connection_sql(): print("用例执行前连接数据库") yield print("用例执行后关闭数据库") @pytest.mark.usefixtures("connection_sql") class TestFirstClass1(): def test_login(self): print("这是登陆测试用例") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例") class TestFirstClass2(): def test_delete(self): print("这是删除测试用例") def test_update(self): print("这是修改测试用例")
function
和class
作用域的Fixture手动使用的会比较多,module
、package
、session
级别的Fixture一般都是自动
4.Fixture中的params参数化(了解即可)
@pytest.fixture(scope="作用范围", autouse=True/False,params="参数化",ids="参数别名",name="Fixture别名")
-
params
:参数化,根据提供的数据组数来决定用例的执行次数。参数值可以是list或tupleimport pytest @pytest.fixture(scope="function", autouse=False, params=["张三", "李四", "王五"]) def connection_sql(request): print("用例执行前连接数据库") yield request.param print("用例执行后关闭数据库") class TestFirstClass(): def test_login(self, connection_sql): print(f"这是登陆测试用例—— {connection_sql}") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例")
十、Pytest测试用例的前后置固件Fixture结合conftest.py文件一起使用
conftest.py
文件是专门用来存放Fixture固件的(文件名是固定的,不可变)conftest.py
文件内的固件在使用时都不需要导包。默认同级或子级的python
文件都可以使用conftest.py
文件可以有多个,作用域都是同级或子级
conftest.py
同样的调用方式,都是自动调用的情况下,外层的优先级高于内层。都是手动调用的情况下,先调用的优先级高于后调用的
十一、Pytest测试框架的执行过程
Pytest的调用流程如下:
- pytest程序启动时,会先加载命令行参数和配置文件
- pytest会根据命令行参数和配置文件中指定的测试文件或目录,找到所有的测试模块和测试函数
- pytest会对找到的测试模块和测试函数进行收集和解析,生成测试用例
- pytest会根据测试用例生成测试执行计划,确定测试的顺序和依赖关系
- pytest会按照测试执行计划,依次执行每个测试用例
- pytest会捕获测试用例的执行结果,并生成测试报告
- pytest会根据配置文件中的设置,执行相应的测试结果处理操作,如生成HTML报告、发送邮件等
- 执行完所有的测试用例后,pytest会输出测试结果统计信息,并退出程序
十二、Pytest测试框架控制测试用例的执行顺序
Pytest默认是从上往下执行测试用例
1.方法一:使用pytest-ordering插件
-
安装
pytest-ordering
插件pip install pytest-ordering
-
使用
@pytest.mark.run(order=number)
进行标记(number数字越小,优先执行级别越高)import pytest class TestFirstClass(): def test_login(self): print("这是登陆测试用例") @pytest.mark.run(order=1) def test_register(self): print("这是注册测试用例") @pytest.mark.run(order=2) def test_add(self): print("这是添加数据用例")
2.方法二:使用pytest-order插件
-
安装
pytest-order
插件pip install pytest-order
-
使用
@pytest.mark.order(number)
进行标记(number数字越小,优先执行级别越高)import pytest class TestFirstClass(): def test_login(self): print("这是登陆测试用例") @pytest.mark.order(1) def test_register(self): print("这是注册测试用例") @pytest.mark.order(2) def test_add(self): print("这是添加数据用例")
十三、Pytest测试框架的基础路径设置
-
使用
pytest-base-url
处理基础路径(测试环境、开发环境、预发布环境、生产环境) -
在测试用例中可以当成是fixtrue手动调用
1.安装
pytest-base-url
插件pip install pytest-base-url
2.基础路径设置
pytest.in全局配置文件
# 基础路径(开发、测试、预发布、生产) base_url = ip地址/端口号
import pytest class TestFirstClass(): def test_login(self,base_url): print(f"这是登陆测试用例 {base_url}") def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例")
十四、Pytest测试框架断言
-
Pytest中断言使用的是Python里面的原生的
assert
断言 -
断言正确则用例执行会通过,断言失败,用例执行会不通过
class TestFirstClass(): def test_login(self): print("这是登陆测试用例") # 断言实际结果是否包含了 "希望" 两个字 assert "希望" in "今天又是充满希望的一天" def test_register(self): print("这是注册测试用例") def test_add(self): print("这是添加数据用例")
十五、Pytest测试框架的parametrize简单数据驱动
-
使用
@pytest.mark.parametrize("参数名", 参数值(可以是list或tuple))
实现数据驱动import pytest class TestFirstClass(): @pytest.mark.parametrize("name,age", [["张三", 18], ["李四", 28], ["王五", 20]]) def test_query(self, name, age): print(name, age)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)