Pinpoint Web 前端 PR 前 QA 关卡:构建、测试与行为回归检查完整指南
【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint
导读:本文讲解 Pinpoint 仓库中为 Web 前端 v3 定制的"PR 前 QA 关卡"(
qa-pr技能)——一套在提交或推送前强制执行的构建、测试与行为回归检查流程。它服务于 Pinpoint APM 的 React 19 前端监控面板(ServerMap 拓扑、散点/热力图、事务列表、Inspector 等)。读完本文,你将掌握如何用「变更识别 → 构建测试 → 行为 QA → Pinpoint 专项回归 → 判定输出」五步流程,把线上缺陷拦截在合入之前,并能理解每步检查背后对应的源码实现与项目架构依据。
一、这份文档是什么:定位、触发时机与执行者
qa-pr是定义在 qa-pr/SKILL.md 中的一条 Claude Code 技能(Skill),其定位在文档头部声明得很清楚:
Pinpoint 프론트엔드 PR 전 QA 게이트. 빌드/테스트를 실행하고 변경된 코드에 대한 동작 QA를 수행합니다. 커밋하거나 PR을 올리기 전에 반드시 이 스킬을 먼저 실행하세요.
(Pinpoint 前端 PR 前 QA 关卡:执行构建/测试,并对变更代码做行为 QA。提交或提 PR 前必须先执行本技能。)
三个关键事实:
- 触发时机是强制的:文档规定"커밋하거나 푸시하기 전에 반드시 실행하세요"(提交或推送前必须执行),并且"QA 판정이 FAIL이면 문제를 해결하기 전까지 커밋하지 마세요"(判定为 FAIL 时,在问题解决前不得提交)。这条规则不是孤立的——项目级的 CLAUDE.md 中"절대 위반 금지 규칙"(绝对不可违反的规则)第 2 条同样写明"커밋/푸시 전에 반드시 /qa-pr 스킬을 실행하세요",git-workflow.md 也在"커밋 전 QA 게이트"一节重复了同样的要求。也就是说,
qa-pr是整个仓库 Git 工作流中不可绕过的质量闸门。 - 执行主体是专用 Agent:该技能通过
.claude/agents/qa-engineer/qa-engineer.md中定义的qa-engineer代理执行,并要求 QA 过程遵循该代理的思维方式、检查清单与输出格式。qa-engineer的角色描述是"Pinpoint Frontend QA 전문가"(Pinpoint 前端 QA 专家),它以测试者而非开发者的视角思考,目标是"프로덕션에 버그가 도달하기 전에 발견"(在缺陷进入生产环境之前发现)。 - 服务于真实前端代码库:被检查的对象是 Pinpoint Web Frontend v3——README.md 所述的 React 19 单仓库(monorepo),包含
apps/web(主应用)与packages/ui、packages/scatter-chart、packages/server-map、packages/datetime-picker四个核心包。
二、第 1 步:摸清变更范围
QA 的第一步永远是先知道"改了什么"。技能要求执行以下两条命令:
git diff upstream/master --name-only git diff upstream/master --stat--name-only列出本次变更涉及的全部文件路径,用于确定 QA 的检查范围;--stat给出每个文件的增删行数统计,用于评估改动规模与风险集中点。
随后需要"列出所有变更文件并总结修改内容"。这一步的意义在于:后续所有构建、测试与行为检查都要围绕这批文件展开,而不是对全仓库做无差别回归。与这条命令配套的仓库约定是:变更分支必须基于最新的upstream/master创建(见 git-workflow.md 的强制分支工作流),因此git diff upstream/master恰好能覆盖"本次 PR 相对主干的全部差异"。
三、第 2 步:构建与测试——第一道自动化关卡
技能要求在识别变更后,按顺序执行:
yarn build yarn test并且明确规定:失败时立即停止并上报,禁止在构建或测试失败的状态下提交("실패 시 즉시 중단하고 보고하세요. 빌드나 테스트 실패 상태에서는 커밋하지 마세요")。
要理解这两条命令到底检查了什么,需要看根目录 package.json 的脚本定义与 CLAUDE.md 的说明:
| 命令 | 实际执行 | 作用 |
|---|---|---|
yarn build | yarn workspace @pinpoint-fe/web build | TypeScript 严格模式类型检查 + Vite 生产构建。CLAUDE.md 明确指出"TypeScript가 첫 번째 QA 게이트"(TypeScript 是第一道 QA 关卡) |
yarn test | yarn workspaces run test | 遍历全部 workspace 包(packages/*、apps/*)执行各自的单元测试 |
针对不同粒度,仓库还提供了细化的测试命令:
# 只跑某个包 yarn workspace @pinpoint-fe/ui test # 只跑某个测试文件 yarn workspace @pinpoint-fe/ui jest path/to/file.test.ts测试规范见 rules/testing.md:采用 Jest + ts-jest preset + jsdom 环境;测试文件与源码同目录存放(*.test.ts/*.test.tsx);模块别名@pinpoint-fe/ui/src/*解析到<rootDir>/src/*。另外仓库还维护了一组基于 Playwright 的 E2E 测试(yarn workspace @pinpoint-fe/web test:e2e),每个页面都有对应的用例文件,例如servermap.e2e.test.ts、scatterFullScreen.e2e.test.ts、transactionList.e2e.test.ts、inspector.e2e.test.ts(位于 packages/ui/e2e/test),它们与后续第 4 步的 Pinpoint 专项回归检查互为印证。
qa-engineer代理对这两步的期望是:分别报告构建与测试的通过/失败状态及错误输出——"각각의 통과/실패 여부와 오류 출력을 보고합니다"。
四、第 3 步:行为 QA——对变更代码做功能分析
构建和测试通过只代表"类型没错、既有断言没破",并不代表"功能真的对"。第 3 步要求对每个变更的组件(component)、Hook、页面(page)做四轮功能分析。
3a. 正向路径(Happy Path)
- 正常数据下期望的行为是什么?
- 实现是否符合该期望?
- 追踪"用户动作 → 状态变更 → UI 更新"的完整链路。
这条链路在qa-engineer的知识库中被明确为项目级数据流模式:
사용자 액션 → 아톰 업데이트 → React Query 리페치 → UI 업데이트 用户动作 → Jotai 原子更新 → React Query 重新拉取 → UI 更新(见 qa-engineer.md 的"데이터 흐름"一节。)文档特别提醒:"이 체인의 어느 링크라도 끊어지면 기능이 손상됨"——这条链上任何一环断裂,功能即告损坏。因此正向路径检查不是"点一下看看",而是沿着这条链逐环验证。
3b. 边界情况(Edge Cases)
对变更的 UI 组件逐项核对以下五个检查点:
- 空/null 数据:API 返回空数组或 null 时渲染什么?
- 加载状态:是否显示骨架屏/转圈动画?快速加载时会不会闪烁?
- 错误状态:API 失败/网络错误时,是否向用户展示错误?
- 边界值:日期范围、分页上限、大数据集。
- 并发请求:快速连点、多标签页切换。
qa-engineer针对 Pinpoint 场景进一步细化了七条必须检查的特有边界(这是第 3b 节检查清单在 Pinpoint 语境下的落地):
- 未选择应用(application):多数页面依赖已选应用,未选择时渲染什么?
- 空时间范围:
from === to或无效日期范围。 - 无数据:API 返回
[]或{}——是否有正确的空状态? - 大数据量:ServerMap 超过 100 个节点、事务列表超过 1000 条——能否不崩溃地渲染?
- 快速导航:页面间快速点击——过期请求与竞态条件。
- 并发 API 调用:多个 Hook 同时执行——加载/错误状态是否正确?
- 配置未加载:
configurationAtom填充完成之前页面就完成渲染。
第 7 条对应的正是 InitialFetchOutlet.tsx 的职责:它在渲染子路由之前先通过useGetConfiguration拉取配置并写入configurationAtom,data或configuration尚未就绪时直接返回null(不渲染子页面),从而避免"配置未到、页面先画"的错位;配置拉取失败则navigate(APP_PATH.API_CHECK)重定向到/apiCheck检查页。
3c. 状态完整性(State Integrity)
- URL 参数是否正确反映 UI 状态(from/to、application)。
- 页面刷新后状态是否保持(URL 是真相的唯一来源)。
- 原子(atom)状态在页面导航之间是否泄漏(确认清理逻辑)。
- React Query 缓存在 mutation 之后是否还显示旧数据。
这四条在源码里都有直接对应物:
- URL 即真相:
searchParametersAtom(见 atoms/searchParameters.ts)保存application与searchParameters键值对,而它的写入发生在InitialFetchOutlet的useEffect中——由useLocation()的pathname/search解析而来,且依赖数组只含applicationName、serviceType、to、from四个字段。这就在结构上保证了"URL 参数变化 → 原子更新"的单向同步。 - 导航间原子不泄漏:
InitialFetchOutlet用key={requestService}强制页面子树在 service 变化时整体 remount;但qa-engineer的"함정"(陷阱)章节专门提醒:"아톰은 화면 remount로 지워지지 않는다"(原子不会随页面 remount 被清空)——key只重置组件 state,跨 service 的选择类原子(如serverMapCurrentTargetAtom)必须显式清理,否则会带着上一个 service 的选择发请求。 - 缓存不过期:React Query 是所有服务端数据的获取层,mutation 后需要使相关 queryKey 失效,否则 UI 会继续展示旧数据。
3d. 组件交互(Component Interaction)
- 变更后的 props 是否满足所有父组件的调用点。
- 事件处理器是否正确触发、且不会产生重复动作。
- 无无限重渲染循环(原子依赖变更、不稳定引用)。
qa-engineer总结了四条真实踩过的交互陷阱,直接为这三个检查点提供判据:
| 陷阱 | 现象 | 判据 |
|---|---|---|
| 不稳定的原子引用 | Object.fromEntries(searchParams)每次渲染都产生新对象 | 直接放进useEffect依赖数组会触发无限循环 |
| 清理函数缺失 | 无清理的useEffect | 内存泄漏、陈旧回调 |
渲染期间调用navigate() | 在 render 阶段直接调用路由跳转 | 必须放进useEffect内部 |
| 类型断言不一致 | Configuration & Record<string, string>与Record<string, unknown>混用 | 检查每个页面是否使用正确的 cast |
五、第 4 步:Pinpoint 专项回归检查
这是整套 QA 流程中最具项目特色的部分——四项针对 Pinpoint 核心页面的回归检查:
- application/from/to 变更时,ServerMap 仍能正常渲染:ServerMap 是依赖 Cytoscape + dagre 布局绘制的应用依赖拓扑图(见 packages/server-map),任何涉及查询参数、service 或路由的改动都可能影响它的数据加载。
- 变更代码附近的散点图交互(拖选、点击)仍然可用:散点图是基于 Canvas 的独立实现 packages/scatter-chart,其拖拽选时间范围是 Pinpoint 核心交互之一。
- 事务列表 / Inspector 导航未被破坏:事务列表与 Inspector 页面的路由与查询参数联动是高频回归区。
- 基于配置的功能仍然正确读取配置:例如
experimental.enableServiceMap这类由配置驱动的开关,改动后必须确认开关读取逻辑没被破坏。
这四项的深层依据散落在仓库的架构规则中。以配置驱动功能为例,rules/service-map.md 记录了严格约定:配置开关只能经由唯一入口useEnableServiceMap()(屏幕内)与getEnableServiceMap()(渲染外)读取,严禁在业务代码里直接读configuration?.['experimental.enableServiceMap.value']——直接读取会导致"屏幕显示与请求头携带的 service 不一致"这类类型检查抓不住的错位。QA 在第 4 步检查"설정 기반 기능이 여전히 설정을 올바르게 확인함"(配置驱动功能仍正确读取配置)时,依据的正是这套约定。
同时,仓库 E2E 测试目录(packages/ui/e2e/test)中按页面组织的servermap、scatterFullScreen、transactionList、inspector、realtimeServerMap、filteredMap等用例,正好覆盖了本步的四项检查对象,可以作为自动化补充。
六、第 5 步:输出回归摘要与 QA 判定
完成全部检查后,必须输出结构化回归摘要,包含五项内容:
- 变更文件:数量与清单
- 执行的测试:通过/失败
- 构建:通过/失败
- 发现的行为问题:按严重度列出
- QA 判定:✅ PASS / ❌ FAIL / ⚠️ PASS WITH WARNINGS
判定为 FAIL 或 PASS WITH WARNINGS 时,必须列出合入前需要完成的具体整改动作。
七、判定标准的支撑:qa-engineer 的严重度分级与报告格式
qa-pr技能要求 QA 过程遵循qa-engineer的检查清单与输出格式,其中最重要的支撑是严重度三分法(见 qa-engineer.md):
| 级别 | 含义 | 典型情形 | 处理要求 |
|---|---|---|---|
| Critical | 阻断 PR | 功能完全不可用;数据丢失或展示错误数据;未捕获异常/白屏;无限循环或内存泄漏 | 必须修复 |
| Warning | 尽量在合入前修复 | 空状态未处理(只剩空白);无加载状态(UX 差);正常使用中出现控制台报错;用any掩盖真实类型问题的 cast | 建议修复 |
| Suggestion | 可转后续 Issue | 边界情况缺测试覆盖;性能隐患(不必要重渲染);可访问性问题(缺 aria 属性) | 记录跟进 |
QA 报告的输出格式也有明确规定("분석된 변경 사항 / 빌드 / 테스트 / 발견 사항(Critical·Warning·Suggestion) / 판정"五段式),并且强调必须具体——"파일 경로와 라인 번호를 포함하세요. '문제를 일으킬 수 있음' 같은 모호한 표현은 사용하지 마세요"(必须包含文件路径与行号,禁止使用"可能引发问题"这类模糊表述)。
qa-engineer的思考方式本身也值得 QA 执行者内化——它假定"버그가 존재한다고 가정"(缺陷必然存在,验证前不做无缺陷判断)、"구현이 아닌 동작을 테스트"(测试行为而非实现)、"사용자 관점에서 사고"(站在用户视角)、"회귀에 집중"(改动前能用的,改动后必须还能用)。这四条与qa-pr的五步流程构成了完整的"态度 + 方法 + 输出"闭环。
八、把 QA 关卡嵌入日常提交流程
qa-pr不是孤立的检查动作,而是仓库 Git 工作流的一环。结合 git-workflow.md,完整流程是:
- 提交前先确认分支:
git branch --show-current,若在master上立即中止,按git fetch upstream master && git checkout -b <branch-name> upstream/master创建新分支——仓库规定任何情况都不允许直接向 master 提交。 - 执行
/qa-pr:跑完上面五步,判定为 FAIL 就停下修复。 - 通过后做自检:重读全部变更代码(查逻辑正确性、排查
console.log等调试残留、确认代码风格)、追踪被改代码的调用方与消费方确认兼容、再次yarn build与yarn test确认通过。 - 提交与推送:commit message 使用
[#issue_number] Description格式(例如[#9520] Preserve timestamp during server map loading),推送前先git rebase upstream/master。
环境前提:仓库要求 Node >= 22.13.1、Yarn 1.22.22(见 package.json 的engines与packageManager字段)。除 QA 用到的build/test外,日常开发还有yarn dev(Vite 开发服务器,端口 3000,/api/*代理到localhost:8080)、yarn lint、yarn clean等命令可供配合使用。
九、相关文件索引
| 用途 | 仓库路径 |
|---|---|
qa-pr技能本体 | web-frontend/src/main/v3/.claude/skills/qa-pr/SKILL.md |
执行代理qa-engineer | web-frontend/src/main/v3/.claude/agents/qa-engineer/qa-engineer.md |
| 项目级规则(含 /qa-pr 强制要求) | web-frontend/src/main/v3/.claude/CLAUDE.md |
| Git 工作流与提交前自检 | web-frontend/src/main/v3/.claude/rules/git-workflow.md |
| 测试框架与模式约定 | web-frontend/src/main/v3/.claude/rules/testing.md |
| 配置驱动功能(enableServiceMap)回归要点 | web-frontend/src/main/v3/.claude/rules/service-map.md |
| URL → 原子同步的关键组件 | web-frontend/src/main/v3/apps/web/src/components/Layout/InitialFetchOutlet.tsx |
| 查询参数原子定义 | web-frontend/src/main/v3/packages/ui/src/atoms/searchParameters.ts |
| 根脚本(build/test 定义) | web-frontend/src/main/v3/package.json |
| 按页面的 E2E 用例 | web-frontend/src/main/v3/packages/ui/e2e/test |
总结:qa-pr是一条"自动化检查 + 行为分析 + 项目专项回归 + 结构化判定"的完整 PR 质量关卡。对维护者而言,它是防止回归的守门员;对贡献者而言,它是把提交做扎实的检查清单。任何触碰 Pinpoint Web 前端的改动,都值得在提交前按这套五步流程完整走一遍——尤其是第 4 步的 ServerMap、散点图、事务列表与配置开关回归,它们正是这个 APM 监控面板最核心、也最容易悄悄出问题的部分。
【免费下载链接】pinpointAPM, (Application Performance Management) tool for large-scale distributed systems.项目地址: https://gitcode.com/gh_mirrors/pi/pinpoint
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考