十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Cypress Reporter 源码级解析:深入测试结果面板(@packages/reporter)的结构、运行机制与本地开发测试

Cypress Reporter 源码级解析:深入测试结果面板(@packages/reporter)的结构、运行机制与本地开发测试 Cypress Reporter 源码级解析深入测试结果面板packages/reporter的结构、运行机制与本地开发测试【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypressCypress 在运行测试时位于运行器Runner侧、负责把 suite/test/hook/command 逐条实时渲染出来的界面就是 Reporterpackages/reporter。本文将以其官方说明 packages/reporter/README.md 为骨架结合该包源码与测试用例剖析测试结果面板的功能构成、数据流与事件协议并给出完整的本地开发、监听构建与自动化测试上手路径。Reporter 是什么一个进程内的测试运行结果视图在 Cypress 的架构里Reporter 并不是独立运行的第三方工具而是 Cypress 运行时渲染层的一部分。它实时展示测试的运行结果其核心能力在 README 中列得很明确一个用于聚焦/展开测试文件列表specs list的按钮展示通过passed、失败failed、待执行pending测试数量的统计展示整个测试运行的总耗时duration提供自动滚动auto-scrolling的开关提供各种运行状态运行中、暂停、已停止等的控制按钮一个命令日志command log里面按层级展示suite套件test测试用例hookbefore/after 等钩子带详细信息的命令command与断言assertion各种失败/错误信息从组件构成上看Reporter 是一个 React 18 MobX 的单页式视图入口 src/main.tsx 中导出的Reporter组件把整块界面组织为顶栏Header 可运行单元树Runnables两个大的区域并对外暴露可注入的renderReporterHeader、runnerStore、statsStore等 props使它既能被 Cypress 的应用界面App/Launchpad嵌入也能在 Cypress-in-Cypress 的测试中以window.render(...)的方式挂载渲染见 main.tsx 中专门为测试预留的window.Cypress分支。顶栏Header三大件specs 开关、统计数据与运行控制顶栏组件定义在 src/header/header.tsx它根据ReporterHeaderProps包含appState、events、statsStore、runnablesStore与当前spec渲染三个部分。1. specs 列表开关按钮Header 左侧是一个图标按钮用于折叠/展开测试文件列表快捷键为F。点击后代码路径为onClick{() { action(toggle:spec:list, () { appState.toggleSpecList() events.emit(save:state) })() }}即先切换appState.isSpecsListOpen状态再通过事件总线把该状态持久化save:state会保存用户偏好。该 UI 行为与appState.setSpecsList(status)/toggleSpecList()一一对应见 src/lib/app-state.ts。2. 统计区Stats与总耗时统计区组件 src/header/stats.tsx 读取statsStore的三个可观察字段numPassed、numFailed、numPending以图标 数字的方式展示数字为 0 时显示占位符--const count (num: number) num 0 ? num : --UI 语义为尚未有结果。总耗时的计算来自 src/header/stats-store.tsstart({ startTime, numPassed, numFailed, numPending })记录_startTime随后每 100ms 通过setInterval刷新一次_currentTimeduration是一个 MobXcomputed值取_currentTime - _startTime的毫秒差暂停时pause()会停掉定时器resume()重新启动运行结束end()停表并做最后一次时间校准统计初始值通过defaults常量集中管理reset()时按该表复位。注意计数规则test:after:run事件触发时Reporter 参考的是测试的_cypressTestStatusInfo.outerStatus外部状态而不是最后一次 attempt 的通过/失败状态避免出现重试后最后一次通过、但整条用例实际判失败的统计错位见 src/lib/events.ts。3. 控制区Controlsrunning / paused / stopped 的状态切换控制按钮组件 src/header/controls.tsx 依据appState的实时状态条件渲染四类按钮暂停时显示 Resume快捷键C点击触发events.emit(resume)运行中且未暂停显示 Stop快捷键S触发events.emit(stop)**空闲未运行**显示 Run All Tests快捷键R触发events.emit(restart)且在 Cypress Studio 单测模式下文案会变为 Run test图标做水平翻转已暂停或运行中曾被暂停时显示单步 Next 按钮快捷键N其 tooltip 会直接展示下一个待执行命令名例如Next : cy.get(...)当nextCommandName为空时按钮置灰不可点。这些 UI 状态由 src/lib/app-state.ts 中的AppState统一管理isPaused、isRunning、nextCommandName、pinnedSnapshotId、studioActive、hasBeenPaused等均为 MobXobservable。其中值得注意的是一对用户偏好 vs 临时状态的区分autoScrollingUserPref用户在偏好设置里选择的值通过setAutoScrollingUserPref()写入autoScrollingEnabled当前生效值。当用户在 open 模式下手动滚动命令日志时运行器会调用temporarilySetAutoScrolling(false)临时停掉自动滚动而不会改动用户的偏好值测试结束时_resetAutoScrolling()会把当前值恢复到偏好所对应的值。命令日志Runnables 数据模型与渲染树Reporter 的主体是命令日志它把一次运行中可执行的单元组织成树状结构。组件入口为 src/runnables/runnables.tsx根据runnablesStore的状态呈现四种界面未就绪显示 Your tests are loading... 的加载动画加载完成但没有测试进入空状态界面提示 Cypress could not detect tests in this file.并提供在 IDE 中打开文件以及启用时使用 Cypress Studio 创建测试的入口运行出错有 error 传入渲染RunnablesError正常渲染RunnablesList.wrap .runnables列表。树中每类节点的数据模型分散在src下的各子目录中可通过顶层文件 packages/reporter/package.json 中的browser: src/main.tsx与入口 src/index.ts 顺藤摸瓜suite套件与 test用例src/runnables/suite-model.ts 与 src/test/test-model.tshookbeforeEach / afterEach 等src/hooks/hook-model.tsUI 见 src/hooks/hooks.tsxcommand命令/断言src/commands/command-model.tsUI 见 src/commands/command.tsx错误与重试 attempt错误模型 src/errors/err-model.ts渲染层还包括错误码帧error-code-frame.tsx、调用栈error-stack.tsxattempt 模型 src/attempts/attempt-model.ts其余还有 routessrc/routes/route-model.ts、agentssrc/agents/agent-model.ts、aliases、sessionssrc/sessions/sessions-model.ts等附属分类。命令日志还支持两种点击后跳转到被测应用的联动点击命令打开对应的快照snapshot相关本地事件为show:snapshot/hide:snapshot/pin:snapshot/unpin:snapshot见 events.ts并可在悬停时固定快照便于检查 DOM点击在控制台展示会把对应命令/错误信息转发给 Driver事件为show:command与show:error映射到 runner 的runner:console:log/runner:console:error。Reporter 与 Runner 的事件协议数据究竟如何流入界面Reporter 本身不执行测试它只是监听 RunnerDriver 进程广播的事件来增量更新 UI。这套协议集中定义在 src/lib/events.ts可将其分为入站runner → reporter与出站reporter → runner两个方向入站事件runner.on(...)注册主要包括事件处理动作runnables:ready把整棵 RootRunnable 写入runnablesStoresetRunnablesreporter:log:add/reporter:log:state:changed/reporter:log:remove命令日志的新增 / 状态变更 / 移除run:start若有测试则置isRunning truereporter:start携带ReporterStartInfo恢复自动滚动偏好、设置滚动位置、Studio 状态并启动计时test:before:run:async/test:after:run标记用例开始 / 结束并累加通过、失败、待执行计数paused记录下一条要执行的命令名供单步 Next 按钮使用run:end停止计时并结束统计reporter:collect:run:state收集当前autoScrollingEnabled与scrollTop供恢复会话用reporter:snapshot:pinned/reporter:snapshot:unpinned同步固定快照到命令日志高亮外部如 tap CLI也能驱动出站方向由localBus一个 NodeEventEmitter实例承载Reporter 内部 UIcontrols、shortcuts、header 等调用events.emit(restart)、events.emit(resume)、events.emit(stop)、events.emit(save:state)等再由 events 层统一翻译成 runner 端事件如runner:restart、runner:resume、runner:stop从而实现点击界面按钮 → 驱动真实测试运行的闭环。save:state持久化的字段autoScrollingUserPref、isSpecsListOpen、showFetchRequests、codeEditorLineWrap定义在 events.ts。这种事件驱动 MobX 可观察 store的设计保证了 Reporter 与真正执行测试的 Runner 之间只需要一条稳定的消息通道而不用关心彼此的渲染细节。内置快捷键一份可直接背诵的交互清单src/lib/shortcuts.ts 实现了 Reporter 的键盘交互它会把 keydown 同时绑定到顶层 document 与 reporter 所在 iframe 的 documentgetReporterDocument()保证焦点在任意文档时快捷键都能生效当焦点在输入框等文本控件、或按下了任意修饰键alt/ctrl/shift/meta时不响应。可用的键位按键动作说明rrestart重新运行全部/单条测试sstop停止运行暂停时不生效ftoggle specs list折叠/展开测试文件列表并保存偏好cresume从暂停处继续nnext单步执行到下一个命令atoggle auto-scrolling切换自动滚动用户偏好并保存开发 Reporter 的正确姿势构建产物与 watch 工作流README 明确建议想要看到 Reporter 真正渲染出来跟随 Developing the driver 的指引把整个 Driver 跑起来再在其中打开测试项目。这是因为 Reporter 是运行器 UI 的一部分单独打开不会自动运行测试必须由 Driver/Runner 作为宿主驱动。watch 构建yarn workspace packages/reporter watch该命令实际指向yarn build-for-tests --watch --progress见 packages/reporter/package.json通过仓库脚本scripts/run-webpack触发打包。构建产出由 packages/reporter/webpack.config.ts 定义入口src目录即 src/index.ts 与 src/main.tsx入口名reporter因此产物为dist/reporter.js样式main.tsx引入的main.scss会被一并编译产物为dist/reporter.cssHTML 壳通过HtmlWebpackPlugin使用 static/index.html 作为模板注入但不自动插入脚本产物的 sourcemap 模板为cypress://[namespace]/[resource-path]便于在 DevTools 中定位到源码文件。说明README 中描述的构建链路为babel 转译*.js/*.jsx browserify 打包 sass 编译这是该包早期的构建方式当前仓库实际已切换为 webpack 统一构建React/TS 组件 Tailwind/PostCSS见 postcss.config.js 与 tailwind.config.js。若想在本地同时看到 Reporter 自身改动与被测试应用改动还需另外跑yarn workspace packages/runner watch组件结构速查Reporter 的源码全部位于 packages/reporter/src按功能拆成一个个小目录建议按数据模型*-model.ts 渲染组件*.tsx 样式*.scss三件套阅读lib/事件总线、AppState、滚动控制器、快捷键、工具函数base 样式也在其base.scssheader/顶栏、统计、运行控制、文件/统计 storerunnables/、test/、hooks/、commands/、errors/、attempts/命令日志的树节点及其子分类agents/、routes/、sessions/、studio/、components/、shared/特定类型日志条目与公共小组件。测试 Reporter 自身Cypress-in-Cypress 的用法Reporter 的质量保障方式与业务项目一致——直接用 Cypress 测试 Cypress。仓库内该包的测试命令为yarn workspace packages/reporter cypress:open按 README 的提示测试时建议同时跑yarn workspace packages/reporter watch # 实时构建 reporter 自身改动 yarn workspace packages/runner watch # 同步主 Cypress 运行器改动这样每次改完源码被测的 bundle 都会即时更新测试里即可迭代验证界面表现。说明一点README 中写测试位于cypress/integration这是较早的目录规范当前仓库的测试已经迁移为 Cypress 10 的cypress/e2e结构实际位于 packages/reporter/cypress/e2e配置文件见 packages/reporter/cypress.config.ts并分成两类组件级测试e2e/unit/直接针对某个 store / 组件单测例如command_model.cy.ts、err_model.cy.ts、runnables_store.cy.ts、scroller.cy.ts、stats_store.cy.ts、suite_model.cy.ts、test_model.cy.ts、events.cy.ts、util.cy.ts、app_state.cy.ts以及组件目录下的*.cy.tsx如 src/commands/command.cy.tsx、src/header/stats.cy.tsx、src/hooks/hooks.cy.tsx端到端功能测试e2e/根下如commands.cy.ts、suites.cy.ts、tests.cy.ts、hooks.cy.ts、header.cy.ts、agents.cy.ts、aliases.cy.ts、routes.cy.ts、runnables.cy.ts、shortcuts.cy.ts、test_errors.cy.ts、memory.cy.ts等对应的 Mock 数据放在 packages/reporter/cypress/fixtures例如runnables.json、runnables_commands.json、command_error.json等。测试执行还有更多 npm scripts 可用均定义于 packages/reporter/package.json无头运行yarn workspace packages/reporter cypress:run、组件测试运行yarn workspace packages/reporter cypress:run:ct、类型检查yarn workspace packages/reporter check-ts、Lintyarn workspace packages/reporter lint。小结一条先看数据模型、再读事件、最后跑 UI的阅读路径如果要在本仓库中研究 Reporter推荐的阅读顺序是读交互清单src/header/stats-store.ts、src/lib/app-state.ts弄清统计与暂停/运行/停止/自动滚动状态从哪来读数据流src/lib/events.ts它是 runner 与 reporter 之间的翻译层几乎所有界面行为都能在这里找到出处读渲染src/main.tsx 与 src/runnables/runnables.tsx看整棵树如何被组织成命令日志跑起来验证yarn workspace packages/reporter watchyarn workspace packages/reporter cypress:open配合cypress/e2e下的测试观察每个交互点。Reporter 的核心价值在于它证明了Cypress 用自己测试自己的可行性被测项目与测试框架共用同一套事件协议与 UI 技术栈这让它的开发与回归测试始终能保持极高的保真度。【免费下载链接】cypressFast, easy and reliable testing for anything that runs in a browser.项目地址: https://gitcode.com/GitHub_Trending/cy/cypress创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表