pytest 动态报告:数据可视化篇 —— 用 Golang + Echo 打造自动化测试任务可视化平台

本文承接前作《pytest 钩子:pytest_report_teststatus 实践》《pytest 钩子:pytest_collection_finish 实践》。前两篇解决了「数据从哪里来」的问题——通过 pytest 钩子上报用例采集与执行结果;本文聚焦「数据到哪里去」——基于 Golang + Echo 搭建一套前后端服务,对钩子上报的数据做汇总、持久化与可视化,最终形成一份可检索、可下钻、可追溯、可扭转的动态测试报告,让 pytest 的产出真正服务于研发与测试协同。


一、背景与整体思路

1.1 为什么需要这层服务

pytest 生态里并不缺报告方案:自带 --html--junit-xml,社区有 allurepytest-reporter 等。但绝大多数方案本质上都是一次性产物,存在几个长期痛点:

  • 跑完才生成:执行过程中无法看到状态,进程被杀或异常退出就一切归零;
  • 每次跑完覆盖:同一份报告文件下一次跑就丢,无法沉淀历史,无法跨任务对比;
  • 失败用例靠记忆:「这条上次是不是同一个问题、上次怎么处理、谁处理过」完全靠人脑记忆与群消息翻屏;
  • 多人多机器散落:本地、CI、定时任务各跑各的,报告文件散落各处,难以统一分发与归档。

而通过 pytest 钩子实时上报 + Golang 后端汇总 的架构,可以把每一次执行沉淀为一条「任务记录」、把每一条用例沉淀为一条「用例记录」,并支持后续的检索、评审、追溯——让报告从一次性产物变成持续演进的资产

1.2 整体架构

┌──────────────┐   pytest hooks     ┌──────────────────────┐        ┌──────────────────┐
│  pytest runner│ ───────────────▶ │  Golang + Echo Server │◀──────▶│  MySQL / Storage  │
│  (collection,  │   HTTP POST       │  /autotest/task/...   │        │  task / case /    │
│   report)     │                    │  REST API             │        │  review / history │
└──────────────┘                    └──────────────────────┘        └──────────────────┘
                                            │
                                            │ JSON
                                            ▼
                                    ┌──────────────────┐
                                    │  Frontend (HTML/  │
                                    │   JS / CSS)       │
                                    │  可视化交互层       │
                                    └──────────────────┘

整体分为三层:

  • 采集层pytest_collection_finish 钩子上报用例采集结果(用例总数、Node ID、markers);pytest_report_teststatus 钩子上报用例执行结果(pass/fail/skip、duration、traceback)。
  • 服务层:Golang + Echo 提供 RESTful 接口,负责数据汇总、查询、评审、历史、导出、生成测试缓存、删除。
  • 展示层:原生 HTML + 原生 JS(无重型框架)实现三层弹窗下钻交互,配合 Toastify 提示。

二、功能总览

整套服务围绕「测试任务」一个核心页面对外暴露能力,自上而下分成四个递进功能:

功能 入口 解决什么
功能 1:任务列表可视化 /autotest/task/index 多任务概览、检索、分发、归档
功能 2:任务详情可视化 列表点「查看」 单任务下钻到用例级
功能 3:失败用例详情与状态扭转 详情中点失败用例 失败用例人工评审与状态扭转
功能 4:用例历史追溯 评审弹窗点「查看历史」 同一用例跨任务的历史轨迹

下面分别展开。


三、功能 1:任务列表可视化

3.1 功能介绍

对测试任务的数据进行简要可视化,作为平台首页与门户。具体能力包括:

  • 对测试任务进行可视化展示,直观展示测试任务用例总数、成功、失败、跳过、未执行等用例状态的数量;
  • 支持对测试任务的过滤搜索;
  • 支持按任务名称、通过率、时间等字段排序;
  • 支持一键导出测试数据;
  • 支持一键生成测试缓存数据。

3.2 字段与交互

任务列表以表格形式呈现,每行对应一次测试任务,列含义如下:

列名 含义 可排序
任务名称 任务的唯一标识,点击可进入任务详情
总数 该任务下用例总数
成功 执行通过的用例数
失败 执行失败的用例数
跳过 被 skip 的用例数
已排查 人工复核过、已确认状态的用例数
未执行 未跑出结果的用例数(unknown)
通过率 Passed / Total 的百分比
时间 任务创建时间
操作 查看 / 导出 / 缓存 三个动作
  • 搜索:顶部搜索框支持按任务名称模糊匹配,点击「搜索」按钮或回车触发,客户端过滤响应极快;
  • 分页:10 / 50 / 100 条每页可切,支持跳转到指定页;
  • 行操作:「查看」进入详情,「导出」生成下载链接,「缓存」生成失败用例缓存压缩包。

3.3 效果

autotest_1


四、功能 2:任务详情可视化

4.1 功能介绍

对测试任务做更详细的可视化,从「任务级」下钻到「用例级」。具体能力:

  • 详细展示测试任务的用例总数与通过率,以及各个状态(成功 / 失败 / 跳过 / 未执行)用例数量;
  • 详细展示测试任务的用例名称、耗时、状态、Node ID 等信息;
  • 支持对测试用例的搜索;
  • 支持按用例状态过滤用例;
  • 支持按用例执行耗时排序。

4.2 筛选与排序

详情弹窗顶部提供三个筛选/排序控件:

  1. 按用例名或 NodeID 筛选:实时 oninput 过滤,匹配用例名或 node_id(如 tests/test_login.py::test_login_ok);
  2. 按结果筛选:下拉框,选项包含 全部 / 通过 / 失败 / 跳过 / 已排查 / 未执行
  3. 按耗时排序:点击「耗时 ↕」按钮在 降序 → 升序 → 不排序 三态之间循环,便于定位最慢用例。

筛选区右侧实时显示 已匹配 / 总数 计数,方便确认当前过滤结果范围。

4.3 用例列表

筛选后的用例以表格呈现,列包括:用例名 / 结果 / 耗时 / Node ID。结果列会附加状态徽标(已排查已标记通过)。对失败或已排查用例,Node ID结果 单元格均可点击,进入失败详情与评审弹窗。

4.4 效果

autotest_2

autotest_3


五、功能 3:失败用例详情与状态扭转

5.1 功能介绍

针对失败用例,在排查过程中为了避免重复排查或排查遗漏,平台引入了「用例状态扭转」机制。具体能力:

  • 展示用例的基本信息(用例名称、当前状态);
  • 展示当前失败的 Traceback(渲染时会把 Error / Exception / Traceback 等关键行高亮,便于一眼定位异常抛出点);
  • 支持状态扭转(已排查 / 标记通过);
  • 支持添加本次排查的备注信息;
  • 支持查看历史排查数据。

5.2 状态扭转的设计意图

pytest 原生结果只有 passed / failed / skipped 三态,缺乏「人工评审」这一维度。平台在用例上叠加了一层 review_status

  • 已排查:明确为「这条失败我看过、是预期内的」,但不改变结论;
  • 标记通过:明确为「这条不再视为失败」,下次回归该用例不再被记为失败。

这样在跨任务对比时,可以快速区分「真正的新增失败」与「已知问题」,让回归报告的可信度大幅提升。

5.3 效果

autotest_4

autotest_5


六、功能 4:用例历史追溯

6.1 功能介绍

「查看历史」用于追溯某个用例过去所有的执行与评审轨迹,对偶发问题、环境问题的判定非常友好。具体能力:

  • 支持展示历史的排查数据(排查人员、时间、排查结果、当时的报错 traceback、备注信息);
  • 支持查看某条历史 Traceback 的详细日志。

6.2 价值

切换查看某条历史 traceback 时,标题会自动改为 (历史 #N:时间),方便区分「最新」与「某次历史」。这样排查同学既能看到「现在长什么样」,也能看到「过去什么时候变过、为什么变」,对偶发问题、环境问题、时序问题的判定非常友好。

6.3 效果

autotest_6


七、与 pytest 钩子的协作

本服务的数据全部由 pytest 端的钩子上报而来,二者协同形成一个闭环。

7.1 pytest_collection_finish:上报采集结果

在用例收集完成后触发,把整批用例的 Node ID、名称、markers 一次性上报到后端,形成「待执行用例」集合。这一步是「未执行(unknown)」状态的来源——后续若某条用例没出现在 pytest_report_teststatus 上报中,则会一直保留为 unknown,便于发现用例被静默 skip / 收集失败的情况。

7.2 pytest_report_teststatus:上报执行结果

每个用例执行完触发,把 pass/fail/skip、duration、traceback 等实时上报,后端据此更新对应用例的状态。这样即便测试中断(如进程被杀),也已经留存了已执行部分的结果,比「跑完才生成报告」的传统方案更稳健。

7.3 1+1>2 的效果

  • 单独的钩子只是「事件源」,没有可视化就只能看日志;
  • 单独的可视化如果数据是静态文件,就失去了「动态、可沉淀」的优势;
  • 钩子 + 服务 的组合,让每一次 pytest 执行都自动成为平台上的一个可查、可评、可追溯的任务,真正实现动态报告。

八、典型使用场景

  1. 回归报告查阅:日常回归跑完后,进入「测试任务」列表,按通过率排序,找到本次回归任务,点「查看」查看失败用例与未执行用例。
  2. 失败用例排查:在任务详情弹窗中按结果筛选 failed,点击失败用例的 NodeID 查看 Traceback,结合堆栈与备注判断是产品 Bug、用例问题还是环境问题。
  3. 状态扭转:确认是已知问题后,在评审弹窗填写备注并点击「已排查」或「标记通过」,下次回归该用例不再被记为失败。
  4. 历史追溯:对偶发失败用例,点「查看历史」回看历次执行与评审记录,对比不同时间点的 Traceback,定位问题是否发生变化。
  5. 结果分发:点击「导出」生成下载链接,复制后贴到群消息或工单中,让相关同学离线查看完整报告。
  6. 缓存重试:点击「缓存」生成失败用例缓存压缩包,提供下载地址,基于失败缓存快速重试失败用例。

九、小结

服务的「测试任务」模块把「跑测试」之后的全部动作都收口到了一个页面里:列表概览 → 用例下钻 → 失败排查 → 评审扭转 → 历史追溯 形成完整闭环。

从技术视角看,它做了三件有价值的事:

  1. 把 pytest 钩子的「事件流」沉淀为「数据资产」——通过 Golang + Echo 把零散的钩子上报聚合为可查询的任务/用例记录;
  2. 把「一次性报告」升级为「动态报告」——支持评审扭转与历史追溯,让用例状态会随着人不断介入而演进;
  3. 把「个人跑测」升级为「团队协同」——导出、缓存、登录态保护,让测试结果天然具备分发与协同属性。

这正是 1+1>2 的效果:pytest 钩子负责「采得全」,Golang 服务负责「存得久、查得动」,前端负责「看得清、用得上」,三者一起构成了一套面向自动化测试结果的实用型可视化平台。


相关阅读


posted @ 2026-08-27 09:05  EXIORAN  阅读(70)  评论(0)    收藏  举报