背景
使用pytest+Allure进行自动化的时候,为了报告展示更明确会使用
with allure.step(xxx)
和
@allure.step(xxx)
测试结束后就可以看到
测试步骤
Allure还支持配置Description
之前直接在case中编写,例如
"""
[用例描述]: 专家问诊
[前置步骤]:
1. 打开h5页面
2. 完成登录
[测试步骤]:
1. 点击问诊后搜索 测试医生数据
2. 点击图文/电话/视频类型问诊
3. 输入病情描述,选择患者
4. 跳转至支付页面
5. 取消订单
[编写人员]: zhongxin
"""
优点
-
内容清晰,由人工编写与确认
缺点
-
更新脚本后可能忘记同步更新
-
没有具体到每一步操作
新方案
新的方案采用读取执行过程中记录的step数据来展示Description
优点
-
根据脚本实时更新
-
具体到每一步的详细操作
缺点
-
具体程度需要根据
allure.step
的编写情况决定 -
执行失败后的步骤不会记录
-
不能记录后置操作
效果
效果
具体编码
在使用allure.step()
的时候
使用的是
def __enter__(self):
plugin_manager.hook.start_step(uuid=self.uuid, title=self.title, params=self.params)
其中start_step
是
@allure_commons.hookimpl
def start_step(self, uuid, title, params):
parameters = [Parameter(name=name, value=value) for name, value in params.items()]
step = TestStepResult(name=title, start=now(), parameters=parameters)
self.allure_logger.start_step(None, uuid, step)
def start_step(self, parent_uuid, uuid, step):
parent_uuid = parent_uuid if parent_uuid else self._last_executable()
if parent_uuid is None:
self._orphan_items.append(uuid)
else:
self._items[parent_uuid].steps.append(step)
self._items[uuid] = step
所以最终每个步骤都被存到了self._items
里面
self._items = ThreadContextItems()
找到allure_commons.reporter.ThreadContextItems
在conftest.py
中编写一个函数来获取这个内容
import allure_commons
allure_commons.reporter.ThreadContextItems._thread_context.items()
然后将里面的内容解析出来
@pytest.fixture(autouse=True)
def case_end():
yield
for k, v in allure_commons.reporter.ThreadContextItems._thread_context.items():
for k1, v1 in v.items():
befores = hasattr(v1, 'befores') and getattr(v1, 'befores') or []
steps = hasattr(v1, 'steps') and getattr(v1, 'steps') or []
for i in befores:
get_steps(i, base_name='前置', exclude=["_session_faker"])
for i in steps:
get_steps(i, base_name='\tcase')
-
@pytest.fixture(autouse=True)
:每次case执行前后自动执行 -
第一行就是
yield
说明函数后面都是后置操作,在case执行结束之后才会去收集step信息
编写get_steps
因为step里面有嵌套,所以使用嵌套函数去逐步解析步骤内容
global names
description = []
names = []
def get_steps(data, base_name, exclude=None):
if exclude is None:
exclude = []
global names
name = getattr(data, 'name')
steps = getattr(data, 'steps')
if name and name not in exclude:
names.append(name)
if not steps and name:
names_text = ""
for index, j in enumerate(names):
if index == 0:
names_text += f"<strong>{j}</strong>"
else:
if index == 1:
names_text += "<ol>"
names_text += f"<li>{j}</li>"
if index == len(names) - 1:
names_text += "</ol>"
if names_text:
description.append(f"<p>「{base_name}」{names_text}</p>")
names = []
return
if steps:
if steps:
for i in steps:
get_steps(i, base_name, exclude)
动态设置description
因为拿到的内容有很多重复,所以使用set进行去重,然后根据原列表的排序方式进行排序
description_set = list(set(description))
description_set.sort(key=description.index)
description_text = "".join(description_set)
description_text = f'<div style="line-height: 16px;font-size: 16px">{description_text}</div>'
description = []
allure.dynamic.description_html(description_text)
完整代码
@pytest.fixture(autouse=True)
def case_end():
yield
global names
description = []
names = []
def get_steps(data, base_name, exclude=None):
if exclude is None:
exclude = []
global names
name = getattr(data, 'name')
steps = getattr(data, 'steps')
if name and name not in exclude:
names.append(name)
if not steps and name:
names_text = ""
for index, j in enumerate(names):
if index == 0:
names_text += f"<strong>{j}</strong>"
else:
if index == 1:
names_text += "<ol>"
names_text += f"<li>{j}</li>"
if index == len(names) - 1:
names_text += "</ol>"
if names_text:
description.append(f"<p>「{base_name}」{names_text}</p>")
names = []
return
if steps:
if steps:
for i in steps:
get_steps(i, base_name, exclude)
for k, v in allure_commons.reporter.ThreadContextItems._thread_context.items():
for k1, v1 in v.items():
befores = hasattr(v1, 'befores') and getattr(v1, 'befores') or []
steps = hasattr(v1, 'steps') and getattr(v1, 'steps') or []
for i in befores:
get_steps(i, base_name='前置', exclude=["_session_faker"])
for i in steps:
get_steps(i, base_name='\tcase')
description_set = list(set(description))
description_set.sort(key=description.index)
description_text = "".join(description_set)
description_text = f'<div style="line-height: 16px;font-size: 16px">{description_text}</div>'
description = []
print(description_text)
allure.dynamic.description_html(description_text)
资源分享
下方这份完整的软件测试视频学习教程已经上传CSDN官方认证的二维码,朋友们如果需要可以自行免费领取 【保证100%免费】