赞
踩
Pytest是一个成熟的全功能的Python测试工具
Pytest是一个成熟的全功能的Python测试工具
简单灵活易上手
支持参数化
支持简单的单元测试和复杂的功能测试,还可以用来做自动化测试
具有很多第三方插件,并且可以自定义扩展
测试用例的skip和xfail处理
可以很好的和Jenkins集成
支持运行由Nose、UnitTest编写的测试用例
pytest主要做什么
Pytest框架安装
pip install pytest
查看Pytest安装版本
pytest --version
requirements.txt
文件:用于存放需要安装的第三方库的名称
(requirements.txt文件名可以自定义)
安装 requirements.txt
文件内指定的第三方库:
pip install -r requirements.txt
有的插件,安装之后,自动启用。有的插件,安装之后,配置后才启用
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
venv
文件)test_
开头或_test
结尾的python
文件Test
开头并且没有__init__
方法的类,从类中按照函数的要求寻找方法
test
开头的函数(1.不能有参数 2.不能拥有返回值)命令行使用pytest
运行
pytest
项目根目录下任意创建一个python文件,编写如下代码,然后运行
import pytest
if __name__ == '__main__':
pytest.main()
查看本文的第五大标题
(最常用,也是用的最多的)
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
参数的使用
test_
开头或_test
结尾的python
文件Test
开头并且没有__init__
方法test
开头无条件跳过
@pytest.mark.skip(reason="无条件直接跳过")
def test_add(self):
print("这是添加数据用例")
有条件跳过
age = 17
@pytest.mark.skipif(age < 18, reason="年龄小于18跳过")
def test_register(self):
print("这是注册测试用例")
一般现在下面的方法使用的都比较少,一般都是使用Fixture实现
setup_method
:前置-用例执行之前
teardown_method
:后置-用例执行之后
# 前置-用例执行之前
def setup_method(self):
print("用例之前执行的代码")
# 后置-用例执行之后
def teardown_method(self):
print("用例之后执行的代码")
注意
:随着Pytest的版本更新可能会无法使用,这里使用的是Pytest 7.4.4 版本进行演示的
setup_class
:类之前
teardown_class
:类之后
# 类之前
def setup_class(self):
print("类之前执行")
# 类之后
def teardown_class(self):
print("类之后执行")
注意
:随着Pytest的版本更新可能会无法使用,这里使用的是Pytest 7.4.4 版本进行演示的
@pytest.fixture(scope="作用范围", autouse=True/False,params="参数化",ids="参数别名",name="Fixture别名")
scope
:作用域(function、class、module、package、session)autouse
:自动还是手动(True代表自动,False代表手动)params
:参数化ids
:参数化别名(不重要,不能单独使用,必须和 params
一起使用,因为它的作用是参数别名)name
:Fixture别名(一旦使用别名,则原来的名称不能再使用了)Fixture支持5级作用域,让用例共享Fixture
function
:每个用例不共享Fixture的返回值,默认class
:每个类中的用例,共享Fixturemodule
:每个模块(文件)中的用例,共享Fixturepackage
:每个包(目录)中的用例,共享Fixturesession
:所有的用例,共享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一般都是自动
@pytest.fixture(scope="作用范围", autouse=True/False,params="参数化",ids="参数别名",name="Fixture别名")
params
:参数化,根据提供的数据组数来决定用例的执行次数。参数值可以是list或tuple
import 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("这是添加数据用例")
conftest.py
文件是专门用来存放Fixture固件的(文件名是固定的,不可变)conftest.py
文件内的固件在使用时都不需要导包。默认同级或子级的 python
文件都可以使用conftest.py
文件可以有多个,作用域都是 同级或子级
conftest.py
同样的调用方式,都是自动调用的情况下,外层的优先级高于内层。都是手动调用的情况下,先调用的优先级高于后调用的Pytest的调用流程如下:
Pytest默认是从上往下执行测试用例
安装 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("这是添加数据用例")
安装 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-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中断言使用的是Python里面的原生的 assert
断言
断言正确则用例执行会通过,断言失败,用例执行会不通过
class TestFirstClass():
def test_login(self):
print("这是登陆测试用例")
# 断言实际结果是否包含了 "希望" 两个字
assert "希望" in "今天又是充满希望的一天"
def test_register(self):
print("这是注册测试用例")
def test_add(self):
print("这是添加数据用例")
使用 @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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。