pytest学习

pytest用例格式
文件 test_开头or_test结尾
类 Test开头
class TestClass:
函数 test_开头
def test_try(self):
断言
assert 表达式返回
测试框架
setup 数据准备
teardown 数据销毁
|setup_module/teardown_module**|全局模块级|**
|setup_class/teardown_class**|类级,只在类中前后运行一次|**
|setup_function/teardown_function**|函数级,在类外|**
|setup_method/teardown_method**|方法级,类中的每个方法执行前后|

参数化
单参数
@pytest.mark.parametrize(‘name’,search_list)
def test_search(name):
assert name in search_list
多参数
@pytest.mark.parametrize(“test_input,expected”,[
(“3+5”,8),(“2+5”,7),(“7+5”,12)
])
def test_mark_more(test_input,expected):
assert eval(test_input) == expected
数据放在列表中
@pytest.mark.parametrize(“test_input,expected”,[
[“3+5”,8],[“2+5”,7],[“7+5”,12]
])
def test_mark_more(test_input,expected):
assert eval(test_input) == expected
用例重命名,加ids参数
@pytest.mark.parametrize(“test_input,expected”,[
(“3+5”,8),(“2+5”,7),(“7+5”,12)
],ids=[‘add_3+5=8’,‘add_2+5=7’,‘add_3+5=12’])
def test_mark_more(test_input,expected):
assert eval(test_input) == expected
中文重命名,需创建下列文件
# 创建conftest.py 文件 ,将下面内容添加进去,运行脚本
def pytest_collection_modifyitems(items):
“”"
测试用例收集完成时,将收集到的用例名name和用例标识nodeid的中文信息显示在控制台上
“”"
for i in items:
i.name=i.name.encode(“utf-8”).decode(“unicode_escape”)
i._nodeid=i.nodeid.encode(“utf-8”).decode(“unicode_escape”)

笛卡尔积 实现 1a,1b,1c,2a,2b,2c,3a,3b,3c

@pytest.mark.parametrize(“b”,[“a”,“b”,“c”])
@pytest.mark.parametrize(“a”,[1,2,3])
def test_param1(a,b):
print(f"笛卡积形式的参数化中 a={a} , b={b}")

测试用例标记
标记方法
方法前添加 @pytest.mark.标记名(str,num,no ios)
执行方法
pytest 文件名.py -vs -m “标记名” ----VS用来打印日志
取消执行时的warning
新建pytest.ini文件,内容如下
[pytest]
makers = 标记名(str)

跳过用例MARK
skip用法
装饰器跳过 @pytest.mark.skip(reason = “跳过原因(代码未实现)”)
@pytest.mark.skopif(sys.123 = true,reason = “跳过原因(代码未实现)”) 满足条件跳过
代码中跳过 pytest.skip (“跳过原因(代码未实现)”),可配合if条件进行实现
xfail用法 用例仍会执行,显示xfail
装饰器 方法一:”@pytest.mark.xfail
方法二:xfail = pytest.mark.xfail
@xfail (reason = “跳过原因(代码未实现)”)
代码 pytest.xfail(reason = “跳过原因(代码未实现)”)

用例执行

界面运行 右键运行,多条可ctrl或shift
命令行运行 (可在结尾添加-V查看具体信息)
进入目录 pytest 执行目录下所有用例
pytest 文件名.py 执行指定文件
pytest 文件名.py::类名 执行指定文件中指定类
pytest 文件名.py::类名::方法名 执行指定文件中指定类的指定方法

用例调度,命令行参数使用
只执行失败测试用例 --lf
险运行失败用例再运行其他 --ff
常用命令行参数
–help
-x 用例一旦执行失败立刻停止
–maxfail = num 执行失败数达到num停止
-m 标记用例
-k “关键字” 执行包含关键字用例
-v 打印详细日志
-s 打印输入详细日志(print内数据)常用-vs
–collect -only (测试平台,pytest自动导入功能)

通过python代码执行pytest用例
方法一:代码中执行
if__name__ = ‘main’:
pytest.main() #运行所有
pytest.main([‘test_mark1.py::tests_dekj’,‘-vs’]) #运行该文件下指定用例
pytest.main([‘test_mark1.py’,‘-vs’,‘-m’,‘dekj’]) #运行该文件下符合关键字用例
#运行方式
python.test_*.py

方法二:命令行中使用,前面加上python -m
python -m pytest

异常处理
方法一:
try:
expect
方法二
pytest.raise()
def test_raise():
with pytest.raise(ValueError)
raise ValueError(‘异常信息话术’)
def test_raise1():
with pytest.raise1(ValueError) as exc_info:
raise ValueError(‘异常信息话术’)
assert exc_info is ValueError
assert exc_info.value.args[0] == ‘异常信息话术’

Pytest 结合数据驱动 YAML

安装:pip install pyyaml
import yaml
file_path = ‘./my.yaml’
with open(file_path, ‘r’, encoding=‘utf-8’) as f:
data = yaml.safe_load(f)

工程目录结构

.
├── data
│ └── data.yaml 存放 yaml 数据文件
├── func
│ ├── init.py
│ └── operation.py 存放被测函数文件
└── testcase
├── init.py
└── test_add.py 存放测试用例文件

Fixture 用法

在需要重复使用的函数上添加装饰器@pytest.fixture()
例:如此,进行查询前会自动调用login,无需在函数中再添加一次login()
@pytest.fixture()
def login()
print(‘登录’)
def serach(login)
print(“查询”)

fixture作用域
@pytest.fixture(scope=function/class/module)
|function|函数级|每一个函数或方法都会调用|
|class|类级别|每个测试类只运行一次|
|module|模块级|每一个.py 文件调用一次|
|package|包级|每一个 python 包只调用一次(暂不支持)|
|session|会话级|每次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法

yield 关键字

@pytest.fixture(scope=function/class/module)
def login()
#setup 准备阶段
print(‘登录’)
token = ‘12344’
username=‘name’
#销毁阶段,可获取返回值
yield token,username
prin(‘登出’)
def serach(login)
token,username = login
print(f’token:{token},username:{username}')
print(“查询”)