1.测试类主函数模式
pytest.main("-s test_abc.py")
# file_name: test_abc.py
import pytest # 引入pytest包
def test_a(): # test开头的测试函数
print("------->test_a")
assert 1 # 断言成功
def test_b():
print("------->test_b")
assert 0 # 断言失败
if __name__ == '__main__':
pytest.main("-s test_abc.py") # 调用pytest的main函数执行测试
2.命令行模式
pytest 文件路径/测试文件名
例如:pytest ./test_abc.py
3. 在第N个用例失败后,结束测试执行
pytest -x # 第01次失败,就停止测试
pytest --maxfail=2 # 出现2个失败就终止测试
4.指定测试模块
pytest test_mod.py
5.指定测试目录
pytest testing/
6.-k 匹配用例名称
通过关键字表达式过滤执行;匹配:可全名,也可以模糊
pytest -k "MyClass and not method"
这条命令会匹配文件名、类名、方法名匹配表达式的用例,这里这条命令会运行 TestMyClass.test_something, 不会执行 TestMyClass.test_method_simple
7. -m 选择对应的标签(mark标签)
标签没有注册,pytest不能识别
PytestUnknownMarkWarning: Unknown pytest.mark.shop - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
@pytest.mark.shop
pyetst.ini配置文件内容:
[pytest]
markers =
login: Run login case
myShop: Run myShop case
一个:
'-m','lesson_add'
多个:
'-m','lesson_add or lesson_list'
排除法:
'-m','not lesson_add '
排除法 多个:
'-m','not (lesson_add or lesson_list)'
8.-v 节点–多层化
示例: test_lesson.py::TesLesson::test_lesson_add # 测试文件::测试类::测试方法
pytest -v test_lesson.py::TesLesson::test_lesson_add
9.-s :显示标准输出,例如print()的语句;
10.-q :显示简洁报告;
11. 多进程运行cases
当cases量很多时,运行时间也会变的很长,如果想缩短脚本运行的时长,就可以用多进程来运行。
安装pytest-xdist:
pip install -U pytest-xdist
运行模式:其中NUM填写并发的进程数。
pytest test_se.py -n NUM
12.重试运行cases
在做接口测试时,有事会遇到503或短时的网络波动,导致case运行失败,而这并非是我们期望的结果,此时可以就可以通过重试运行cases的方式来解决。
安装pytest-rerunfailures:
pip install -U pytest-rerunfailures
运行模式:NUM填写重试的次数。
pytest test_se.py --reruns NUM
13.高阶用法
13.1.跳过测试函数
在我们自动化测试过程中,经常会遇到功能阻塞、功能未实现、环境等一系列外部因素问题导致的一些用例执行不了,这时我们就可以用到跳过skip用例,如果我们注释掉或删除掉,后面还要进行恢复操作。
跳过–skip-------相当于注释的效果
有条件的跳过–skipif–-在执行过程中会对项目的一些前置条件进行判断**
如果您希望有条件地跳过某些内容,则可以使用skipif代替。 if条件为真,跳过
根据特定的条件,不执行标识的测试函数.
方法:
skipif(condition, reason=None)
参数:
condition:跳过的条件,必传参数
reason:标注原因,必传参数
使用方法:
@pytest.mark.skipif(condition, reason="xxx")
import pytest
class Test_ABC:
def setup_class(self):
print("------->setup_class")
def teardown_class(self):
print("------->teardown_class")
def test_a(self):
print("------->test_a")
assert 1
@pytest.mark.skipif(condition=2>1,reason = "跳过该函数") # 跳过测试函数test_b
def test_b(self):
print("------->test_b")
assert 0
执行结果:
test_abc.py
------->setup_class
------->test_a #只执行了函数test_a
.
------->teardown_class
s # 跳过函数```
代码实际应用:
@pytest.mark.shop#增加标签 mark
@allure.epic('外卖项目-接口测试')
@allure.feature('店铺模块')#测试类
class TestShop:
def setup_class(self):#使用这个类就一定会调用这个方法,只能运行一次
#1- 登录
self.token = Login().login({'username':'sq0777','password':'xintian'},getToken=True)
#2- 创建一个店铺的实例
self.shop = Shop(self.token)
#1- 列出店铺
#没有返回返回值的fixture
# @pytest.mark.usefixtures('shop_xt')
#@pytest.mark.skip(reason='下面接口后端存在问题,先跳过不执行!')#无条件跳过下面的用例执行--相当于注释--报告会显示
@allure.story('店铺列出')#接口的名称
@allure.title('店铺列出用例') # 用例的标题
@pytest.mark.shop_list# 增加标签 mark
@pytest.mark.parametrize('inData,respData',get_excelData('我的商铺','listshopping'))
def test_shop_list(self,inData,respData):
#1- 调用店铺列出接口
#店铺实例的创建必须要登录--需要一个店铺的实例---才能使用对应的方法
#调用对应的方法
res = self.shop.shop_list(inData)
'''
如果断言不是一个属性,需要多个组合判断?
原理:assert 布尔表达式 多个条件使用and or
'''
if 'code' in respData:
assert res['code'] == respData['code']
else:
assert res['error'] == respData['error']
#2- 店铺更新
# @pytest.mark.skipif(Login().login({'username':'sq0777','password':'123456'})['msg']!='成功',
reason='登录失败,先跳过不执行下面的接口!') # 条件为真,跳过下面的用例执行
@allure.story('店铺更新') # 接口的名称
@allure.title('店铺更新用例')#用例的标题
@pytest.mark.shop_update # 增加标签 mark
@pytest.mark.parametrize('inData,respData', get_excelData('我的商铺', 'updateshopping'))
def test_shop_update(self,inData,respData,shop_update_init):#引入初始化方法名字
#1- 调用店铺更新的接口
#shop_update_init[0],shop_update_init[1] 返回值0 返回值1
#res = self.shop.shop_update(inData,shop_update_init[0],shop_update_init[1])
#excel测试用例数据,店铺的id,图片信息
#用例执行步骤
with allure.step('第1步:登录'):
print('登录')
with allure.step('第2步:店铺更新操作'):#计算这一步的时间--执行时间
res = self.shop.shop_update(inData,shop_update_init[0],shop_update_init[1])
#2- 断言
assert res['code'] == respData['code']
13.2标记为预期失败函数
标记测试函数为失败函数
方法:
xfail(condition=None, reason=None, raises=None, run=True, strict=False)
常用参数:
condition:预期失败的条件,必传参数
reason:失败的原因,必传参数
使用方法:
@pytest.mark.xfail(condition, reason="xx")
import pytest
class Test_ABC:
def setup_class(self):
print("------->setup_class")
def teardown_class(self):
print("------->teardown_class")
def test_a(self):
print("------->test_a")
assert 1
@pytest.mark.xfail(2 > 1, reason="标注为预期失败") # 标记为预期失败函数test_b
def test_b(self):
print("------->test_b")
assert 0
执行结果:
test_abc.py
------->setup_class
------->test_a
.
------->test_b
------->teardown_class
x # 失败标记