You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在pytest测试场景下自定义Allure报告图片并标注点击位置?

问题解答

1. pytest执行过程中点击位置的记录方案,以及allure.dynamic.label的适用性

allure.dynamic.label不适合用来记录点击坐标这类信息。这个方法的作用是给测试用例打全局元数据标签,比如标注用例所属模块、优先级、负责人这类静态分类属性,数据存在用例的顶层属性位,既没法和单次操作的时序绑定,也不能关联到失败时刻的上下文,完全不匹配操作坐标的记录需求。
可落地的记录方式如下:

  • 基于pytest fixture做用例级的操作上下文缓存。写一个function级别的fixture,每个用例执行时初始化一个空列表存储点击记录;把你业务里封装的点击方法(适配Selenium/Appium/Playwright都可以)和这个fixture绑定,每次执行点击前先算好实际点击的坐标(一般取元素中心点),和元素描述、操作时间戳一起存入列表。
  • 操作和Allure步骤绑定。用allure.step装饰每次点击操作,步骤描述里可以直接带上当前点击的坐标信息,方便在报告的步骤流里对应查看。
  • 失败时做上下文关联。通过pytest_runtest_makereport钩子监听用例执行结果,当捕获到用例失败/报错时,拉取当前用例fixture里存的全量点击记录,和当前截取的屏幕快照做绑定,供后续标记使用。
    核心逻辑参考代码:
# conftest.py 中实现点击记录fixture
import pytest

@pytest.fixture(scope="function")
def click_tracker():
    click_records = []
    def track(x, y, element_desc=""):
        click_records.append({"x": x, "y": y, "desc": element_desc})
    yield track, click_records
    click_records.clear()

# 自定义点击方法示例
def perform_click(element, click_tracker):
    track_func, records = click_tracker
    # 计算元素中心点作为实际点击坐标
    loc = element.location
    size = element.size
    click_x = loc["x"] + size["width"] // 2
    click_y = loc["y"] + size["height"] // 2
    # 先记录再执行点击
    track_func(click_x, click_y, str(element))
    element.click()

2. Allure报告中截图添加点击标记的实现方案

不要等Allure报告生成完成后再去修改嵌入的截图——Allure生成报告时会把所有附件打包成静态资源,后期改静态文件不仅要找对附件的存储路径,还容易破坏报告的索引结构,维护成本极高。
正确的实现逻辑是:在把截图附加到Allure之前,就完成点位标记的绘制,直接上传处理好的带标记截图。
具体实现步骤:

  • 用例失败触发截图时,先把原始截图保存到本地临时目录,不要直接调用allure.attach上传。
  • 从当前用例的click_tracker缓存里取出需要标记的点击坐标(一般标记失败前最后1-3次点击即可,避免标记太多看不清),用Pillow库打开原始截图,在对应坐标位置绘制圆形标记,可搭配序号、操作说明文字提升可读性。
  • 标记绘制完成后,再调用allure.attach把处理后的截图附加到失败用例的报告内容中,需要留存原始截图的话也可以把原图单独附加,命名区分即可。
    绘制标记的参考代码:
from PIL import Image, ImageDraw

def add_click_marks(raw_img_path, click_points, output_img_path):
    """
    raw_img_path: 原始截图本地路径
    click_points: 待标记坐标列表,格式为[(x坐标, y坐标, 操作描述), ...]
    output_img_path: 标记后截图的保存路径
    """
    img = Image.open(raw_img_path)
    draw = ImageDraw.Draw(img)
    mark_radius = 10
    # 红色描边做标记点,黄色字写标注
    mark_outline = (255, 0, 0)
    text_color = (255, 255, 0)
    for idx, (x, y, desc) in enumerate(click_points, 1):
        # 画圆形标记圈
        draw.ellipse(
            (x - mark_radius, y - mark_radius, x + mark_radius, y + mark_radius),
            outline=mark_outline,
            width=3
        )
        # 标注点击序号和说明
        draw.text(
            (x + mark_radius + 3, y - mark_radius),
            f"点击{idx}: {desc}",
            fill=text_color
        )
    img.save(output_img_path)

注意:移动端测试场景下要提前做坐标换算,对齐截图分辨率和点击事件的坐标系——比如部分设备要扣除状态栏高度、部分框架返回的坐标是逻辑分辨率而非物理分辨率,提前换算完再画标记,避免点位偏移。


内容的提问来源于stack exchange,提问作者stcnchenxin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:33:28