6、接口测试 - 用例定制化执行及 Allure 报告

一、 用例定制化执行

1. mark 标签的使用

在测试类、测试方法前使用 :@pytest.mark.标签名

标签名 尽量使用 类的名称 或 测试方法的名称,以便后续调用

2. 运行 mark 标签

1.运行一个 标签(’-m’, ‘标签名 ‘)

1
pytest.main(['测试文件.py', '-s', '-m', '标签名', '--alluredir', '../report/tmp'])

2. 运行多个 标签(’-m’, ‘标签名 or 标签名’)

1
pytest.main(['测试文件.py', '-s', '-m', '标签名 or 标签名', '--alluredir', '../report/tmp'])

3. 排除一个标签(’-m’, ‘ not 标签名 ‘)

1
pytest.main(['测试文件.py', '-s', '-m', 'not 标签名', '--alluredir', '../report/tmp'])

4. 排除多个标签(’-m’, ‘not (标签名 or 标签名)’)

1
pytest.main(['测试文件.py', '-s', '-m', 'not (标签名 or 标签名)', '--alluredir', '../report/tmp'])

3. 解决 标签未注册问题

安装 ini 插件

在项目根目录 创建 pytest.ini 文件

pytest.ini 中 注册 标签

1
2
3
4
5
6
7
# pytest.ini

[pytest]
markers =
shop: shop
shop_list: shop_list
shop_update: shop_update

4. pytest 执行参数

  • -k :匹配用例名称
    • 匹配: 可以全名,也可以模糊
      • lesson_1.py lesson_2.py —- 需要指定运行 2 个
      • pytest -k lesson
  • -v : 节点 —- 多层化
    • test_lesson.py::TesLesson::test_lesson_add # 测试文件::测试类::测试方法
    • pytest -v test_lesson.py::TesLesson::test_lesson_add
  • -sq : 简化打印信息
    • -s : 输出打印
    • -q : 简化打印信息

5. 跳过 、条件跳过

pytest.main(['-rs','test01.py'])-rs执行,跳过原因才会显示

  • 跳过 — skip

    • 使用 跳过 装饰器 标记,可以传递一个可选的原因
    1
    2
    3
    4
    5
    6
    7
    8
    9

    @pytest.mark.skip(reason='我就是不需要执行下面的接口')#一定不执行下面的接口

    @pytest.mark.parametrize('inData,respData', get_excelData2('我的商铺', 'updateshopping'))
    def test_shop_update(self, inData, respData, update_shop_init): # 列出商铺
    res = MyShop(self.token).shop_update(inData, update_shop_init[0], update_shop_init[1]) # 商铺列出方法
    # shopId,imageInfo---对应的---update_shop_init[0],update_shop_init[1]
    print('update_shop_init:--->', update_shop_init[0], update_shop_init[1])
    assert res['code'] == respData['code']
  • 有条件跳过 — skipif

    • 在执行过程中会对项目的一些前置条件进行判断
    1
    2
    3
    4
    5
    6
    7
    8
    9

    @pytest.mark.skipif(1!=2,reason='我就是不需要执行下面的接口') # 条件为真,就跳过

    @pytest.mark.parametrize('inData,respData', get_excelData2('我的商铺', 'updateshopping'))
    def test_shop_update(self, inData, respData, update_shop_init): # 列出商铺
    res = MyShop(self.token).shop_update(inData, update_shop_init[0], update_shop_init[1]) # 商铺列出方法
    # shopId,imageInfo---对应的---update_shop_init[0],update_shop_init[1]
    print('update_shop_init:--->', update_shop_init[0], update_shop_init[1])
    assert res['code'] == respData['code']

二、 Allure 报告优化

1. Allure 标签层级

使用方法层级参数说明
@allure.epic()项目级敏捷里面的概念, 定义史诗,往下是 feature
@allure.feature()模块级(类)功能点的描述,往 下是story
@allure.story()用户故事(方法)用户故事,往下是 title
@allure.title(用例的 标题)用例的 标题重命名html报告名 称
@allure.testcase()测试用 例的链 接地址对应功能测试用例 系统里面的case
@allure.issue()缺陷对应缺陷管理系统 里面的链接
@allure.description()用例描 述测试用例的描述
@allure.step()操作步 骤测试用例的步骤
@allure.severity()用例等 级blocker,critical, normal,minor, trivial
@allure.link()链接定义一个链接,在 测试报告展现
@allure.attachment()附件报告添加附件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pytest
import allure
@allure.feature('这里是一级标签')
class TestAllure():
@allure.title("用例标题0")
@allure.story("这里是第一个二级标签")
@allure.title("用例标题1")
@allure.story("这里是第二个二级标签")
def test_1(self):
allure.attach.file(r'E:\Myproject\pytest-allure\test\test_1.jpg', '我是附件截图的名字',attachment_type=allure.attachment_type.JPG)
@allure.title("用例标题2")
@allure.story("这里是第三个二级标签")
@allure.severity("critical")
@allure.description("这里只是做一个web ui自动化的截图效果")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 测试类--标签mark
@pytest.mark.shop
@allure.epic('外卖系统---史诗级别epic')
@allure.feature('商铺模块')
class TestMyShop: # 测试类---逻辑关系
def setup_class(self): # 每一个类下面所有的方法调用只运行一次
self.token = Login().login({'username': 'sq0001', 'password': '123456'}, getToken=True)

@allure.story('商铺编辑')
@allure.title('商铺列出用例')
@allure.severity('blocker')
@allure.issue('https://www.baidu.com')
@pytest.mark.shop_update # 测试方法--标签mark
@pytest.mark.parametrize('inData,respData', get_excelData2('我的商铺', 'updateshopping'))
def test_shop_update(self, inData, respData, update_shop_init): # 列出商铺
'''
这个是测试用例的描述:
1--xxx
2-xxxx
'''
res = MyShop(self.token).shop_update(inData, update_shop_init[0], update_shop_init[1]) # 商铺列出方法
print('update_shop_init:--->', update_shop_init[0], update_shop_init[1])
assert res['code'] == respData['code']

2. 用例级别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pytest
import allure

@allure.severity("normal")
def test_case_1():
'''修改个人信息-sex参数为空'''
print("test case 11111111")

@allure.severity("critical")
def test_case_2():
'''修改个人信息-sex参数传F和M两种类型,成功(枚举类型)'''
print("test case 222222222")

@allure.severity("critical")
def test_case_3():
'''修改个人信息-修改不是本人的用户信息,无权限操作'''
print("test case 333333333")

@allure.severity("blocker")
def test_case_4():
'''修改个人信息-修改自己的个人信息,修改成功'''
print("test case 4444444")

def test_case_5():
'''没标记severity的用例默认为normal'''
print("test case 5555555555")
1
pytest -sq --alluredir=../report/tmp --allure-severities=normal,critical

3. 显示 allure 环境

allure-results 报告之前,创建 environment.properties或者environment.xml文件

1
2
3
4
5
6
7
# report/tmp/environment.properies

Browser=Firefox
Browser.Version=77
Stand=songqin_teach
ApiUrl=127.0.0.1/login
python.Version=3.6