test: [ENG-08] add verified TS coverage and paired performance reports

This commit is contained in:
Harvey Zhao committed 2026-09-11 22:01:48 +08:00
1 parent 8ed0a5228c
commit 4a9a26d4fc
38 files changed
+24335 -61

No files matched your search

File diff suppressed because it is too large. Load diff
@@ -0,0 +1,46 @@
# ENG-08 覆盖率、资源与性能报告
本任务接在 CORE-23(8ed0a522)之后。目标是让真实覆盖缺口、资源清理失败和性能/体积审查信号可重复检查,不能用工具生成成功代替核心验收。
## 实现与兼容边界
- 新增开发依赖 c8 12.0.0,固定 Yarn 1.22.22;frozen install 已通过。没有新增包运行时依赖、版本变更或公开导出。
- test:coverage 复用 test:unit 的明确用例列表。覆盖率模式生成带完整映射的文件模块,正常测试加载方式保留;按进程隔离临时模块和每次报告,禁用测试构建 tree shaking。原始 V8 收集和归一化映射分别保存,不修改 node_modules。
- sourceInventory 自动纳入未加载源码并明确排除类型文件及已审计第三方文件。关键文件门槛检查实际计数、拒绝零分母、缺失文件、忽略计数与未登记 suppression。类型排除通过 TS 编译后的空模块判断,非简单按文件名猜测。
- 资源适配器四处初始化空 cleanup 和关闭后的空释放统一为无状态内部函数,减少重复闭包分配。实际注册后的闭包和资源所有权仍独立,取消句柄重复调用安全;没有改变公开方法的返回值、事件顺序或 callback this。
- 新增容器预约/失败回滚、直接 scope 释放和聚合清理异常测试。针对新增统计规则,不降低已有门槛,也不执行不可到达回调来增加数字。
- 性能执行、输入/压缩、夹具适配、验证和摘要分离。复用 BASE-06 的同一测量体,仅适配产物 URL 与报告传输;旧冻结 fixture 和既有发布来源验证保留。新旧包相同场景各一次预热、五次正式样本,三组交替配对,资源探针在计时之后独立运行。
- 性能必须使用隔离安装包,校验分发哈希、构建 Node/依赖/脚本、当前包源码和声明来源,拒绝陈旧构建。体积比较三个相同格式入口的实际发布/候选字节,gzip9/Brotli6 沿用原设置。
- Ubuntu/Windows 覆盖率 job 和 macOS 浏览器后顺序配对均写入 Node CI,保留失败证据与摘要,SHA 固定 action、只读权限不变。本次未推送,远端 CI 结果不能由本地结果代替。
## 失败证据与修正
首轮原始 c8 报告声称生命周期行覆盖率 100%,却缺少函数/分支。实际 V8 数据与单独转换均有有效记录;问题在于 Node source-map-cache 中的 file URL 被 c8 本地路径过滤器排除。v8-to-istanbul 默认行计数仍为一,形成虚假高值。保留原始 JSON,独立转换目录归一化路径后,未执行代码和真实分支恢复统计。映射源码还必须匹配本轮源码哈希,拒绝过期/缺失映射。
真实 esbuild/Vite canary 同时验证:完整执行通过、未执行 return 行仍为零、未导入文件留在分母、未执行分支触发门槛。另有空分母、跳过计数和错误百分比检查,不能只检查命令退出码。原失败日志和首轮数据保留在本地缓存。
完整 CI 476 项通过(440 单元、11 工程、25 基线),249 个生产 TS 文件严格检查、37 个公共声明无漂移。覆盖率命令自身还先运行两项真实映射/门槛测试。当前 224 个运行时文件、26 个明确排除,行 60.94%、分支 86.55%、函数 66.71%;四个关键文件的三类指标均为 100%。这是 c8 对 Node 用例的统计,不能等同全部浏览器路径或全生态覆盖率。
## 性能信号与交接
首轮三引擎配对检查全部执行完成,54 次候选资源探针通过;现代核心 gzip 从 35486 增至 58374 字节,核心三个分发格式均超过体积审查阈值。首轮 Firefox/WebKit 个别组构造耗时也出现信号,尚未确认跨组稳定回归。ENG-PERF-01/02 保持 open,交 CORE-22/REVIEW-01 归因、优化及复核。
计时和体积状态 review-required 与资源硬失败分开保存。测试退出零只证明报告有效、配对完整和候选资源要求通过;不能据此发布或关闭风险。没有修改阈值、覆盖历史基线或将旧版定时器残留作为候选允许值。物理设备、屏幕阅读器和浏览器/GPU 原生内存仍有独立发布验收范围。
## 最终验收与提交
| 项目 | 结果 |
| --- | --- |
| 源码和类型 | 原定四个生命周期门槛通过,249 个生产 TS 严格检查,37 个声明无漂移;476 项 CI 通过 |
| 安装包兼容 | run-LF1aXT 的 34 项运行时、5 组旧类型/8 组精确类型通过,零类型阻塞 |
| 生成产物 | 按正式 build/build:i18n 重建;113 个包分发/声明及 docs 编译文件与隔离安装指纹一致;三个导入检查通过 |
| 真实浏览器 | modern 与 legacy 各 114 项资源、实例、字幕生命周期回归通过,三引擎各 38 项,没有失败、重试或跳过 |
| 配对报告 | 最终三引擎各三组配对,54 次候选资源探针通过;Chromium/Firefox 无计时信号,WebKit 第一组 core/chapter 各 +3 ms,其余两组不触发 |
| 性能审查 | 核心三格式体积增长与间歇计时信号保持 review-required;ENG-PERF-01/02 open,不作为发布放行 |
| 工程与文档 | frozen install、actionlint 和 diff 检查通过;源映射、报告规则、运行命令、CI 限制及模块职责已同步 |
[冻结证据](../baselines/quality-validation.json) 保留源码/工具/测试指纹、原始与归一化 V8 哈希、有效覆盖率、配对完整数据、隔离安装类型/运行时检查及两种格式浏览器结果。首轮失败和间歇性能信号的日志指纹单独保留,不覆盖历史。
提交前最后审查为覆盖率 job 明确 bash shell,使 Windows 的多行安装步骤也在中途原生命令失败时停止,避免仅以末条命令状态误判。只调整工作流执行约定,重新通过 actionlint;此前未提交的证据副本保存在本地缓存 quality-before-ci-review.json,最终冻结证据绑定修正后的工作流哈希,生产代码和浏览器产物未变。
ENG-08 done,59 done、155 todo。本任务独立本地 commit 包含实现、测试、文档、任务状态和生成产物;提交核实后开始 CORE-22。没有 push/publish/tag/merge。回退时整体回退本任务实现、开发依赖/锁文件、CI、测试、生成产物和文档,保留前置 CORE-23 的接口与声明成果。
+62
View File
@@ -0,0 +1,62 @@
# 覆盖率、资源与性能报告
本文由 ENG-08 维护。覆盖率和资源/性能配对链路已通过工程验收,见 [冻结证据](baselines/quality-validation.json)。报告工具通过不等于核心或发布验收通过。
## Node 单元覆盖率
使用固定 Node 24.21.0、Yarn 1.22.22,运行 `yarn test:coverage`。新增开发依赖 c8 12.0.0 仅在仓库测试中使用,不进入发布包的运行时依赖。版本由根 package.json 和 yarn.lock 固定。
执行顺序:真实映射回归测试 → package.json 中同一份 test:unit 用例列表 → Node V8 原始收集 → 源码映射检查与路径归一化 → c8 报告 → 关键文件门槛。正常 test:unit 仍使用原加载路径;覆盖率模式为每个进程生成带 inline source map 的模块,并关闭测试构建的 tree shaking,防止未使用代码从分母消失。此模式不是发布构建配置。
| 文件 | 职责 |
| --- | --- |
| scripts/coverage.mjs | 编排收集、报告和门槛,使用全新的 run-* 目录 |
| scripts/coverage-maps.mjs | 保留原始 V8 JSON;核对映射内源码与本轮源码 SHA-256;在独立目录把 file URL 转为本地路径 |
| scripts/coverage-report.mjs | 枚举真实源码,检查报告文件清单和计数,按有效计数重新计算百分比 |
| scripts/coverage-policy.json | 已纳入的包、明确排除理由及关键模块门槛 |
| test/coverage.test.js | 实际运行 esbuild/Vite 两种加载器;验证未执行分支/未导入文件、空计数、缺失/过期映射和跳过计数不能伪装通过 |
当前纳入 artplayer 与 artplayer-plugin-chapter。224 个运行时文件进入分母;25 个仅类型文件和 1 个第三方 screenfull 文件单独列出,保留内容哈希和排除理由。后续迁移生态包时扩展 packages 与对应风险门槛,不得声称已经覆盖全部 22 个包。
| 关键文件 | 行最低值 | 分支最低值 | 函数最低值 |
| --- | --- | --- | --- |
| lifecycle/scope.ts | 95% | 90% | 95% |
| lifecycle/resources.ts | 95% | 90% | 95% |
| lifecycle/instance.ts | 95% | 90% | 95% |
| source/operation.ts | 90% | 85% | 90% |
以上是原始门槛,未为通过检查降低。关键指标分母为零直接失败。总覆盖率用于显示缺口,不替代功能验证;未执行的浏览器 DOM 路径仍显示为 Node 覆盖率缺口。不能将 Node 和浏览器的用例数相加后声称覆盖率提高。
`refactor/.cache/coverage/latest.json` 指向本次报告目录。run-* 中保存 inventory.json、c8.json、report.json、原始 raw/、归一化 normalized/、测试模块 modules/ 和 HTML/JSON/LCOV 报告。原始收集文件保持不变;report.json 保存归一化前后 SHA-256。失败记录保持 failed,不自动更新冻结基线。
### 映射问题与生命周期补测
首轮报告中,生命周期文件出现 100% 行覆盖率且函数/分支分母为零。原始 V8 包含有效分支,直接转换也有有效分支;c8 在 applyCoverage 阶段按文件路径过滤,而 Node 缓存中的 sources 是 file URL,两者不一致导致有效范围被过滤,默认行计数却保留。先保留原始数据,再将 sources 归一化即可恢复。回归用例同时检查未执行 return 行仍为零,不能只断言报告生成成功。没有修改 node_modules 或绕过 c8 过滤器。
补充了容器竞争与失败回滚、直接 scope 释放、多个清理异常仍释放预约的单元用例。资源适配器重复创建的无状态空 cleanup 合并为一个内部函数;实际注册的释放句柄仍独立。封闭 scope 返回的监听器/定时器/RAF 句柄重复调用不产生晚到回调。此处不是公开方法或导出调整。
### CI
Node CI 新增 Ubuntu/Windows 覆盖率 job,验证固定工具链并运行完整覆盖率命令,失败时也上传报告及原始映射证据。权限仍为 contents:read,未引入第三方覆盖率服务。仓库尚未推送,远端两个系统的执行结果尚待验证;本机 Windows 通过不能冒充 Linux CI 结果。
## 资源与性能验收
沿用 BASE-06:至少三组同环境旧版/候选配对,交替顺序;每种配置一次预热和五次计时样本。构造/就绪/播放 Promise/销毁阈值为 max(25%, 对应绝对值 2/50/10/2 ms)。压缩采用原始字节、gzip 9、Brotli 6,匹配相同格式与入口,增长超过 max(5%, 1024 bytes) 触发审查。
计时和体积触发审查不等于资源泄漏。候选资源检查严格要求销毁后无实例、DOM、proxy 监听器、RAF、剩余定时器和晚到回调,不以旧版 BASE-PERF-01 的残留作为容许值。计时阶段不装资源探针,资源探针清理自身计时器发生在记录之后。物理设备、GPU/浏览器原生内存仍不能靠这些计数证明无泄漏。
先运行 `yarn test:package`,将 ARTPLAYER_BROWSER_ARTIFACTS 设为生成的 browser-artifacts.json,再执行 `yarn test:performance`。单独的 Playwright 配置按单 worker 运行三种引擎,关闭 trace/video,禁止与其他浏览器或重型构建任务同时计时。测试复用冻结 BASE-06 测量体,仅通过适配器修改脚本 URL 和报告提交方式,原始 fixture 不变。加载前检查包源码/声明来源、构建脚本、依赖和分发哈希,旧产物不能代替当前源码。
scripts/performance-artifacts.mjs 管输入和压缩,performance-fixture.mjs 管冻结 fixture 适配,performance-report.mjs 管配对与资源门槛,performance-summary.mjs 输出审查表;test/performance/paired.spec.js 管真实浏览器执行,test/performance-report.test.js 覆盖不完整配对、换环境、假播放、资源残留、过期源码和改动产物等失败。共享的测量验证从原 performance.mjs 提取为函数,旧发布基线仍保留完整来源校验。
报告保存于 refactor/.cache/performance/run-<engine>-*/report.json 和 summary.md;失败或未完成状态保留,Playwright JSON 与附件另存 browser/。Node CI 在安装包浏览器功能测试后顺序运行配对,追加 GitHub 摘要并上传报告。远端 macOS 执行尚未发生,本地 Windows 不替代该项环境验证。
退出零表示测量完整性、配对规则及候选资源检查通过;review-required 明确表示仍有计时或体积审查信号。该信号不自动失败工程报告生成,也绝不作为发布放行:CORE-22/REVIEW-01 必须处理风险台账。不得把报告改为 passed、抬高阈值或覆盖历史基线来隐藏增长。
### 首轮观测与待审查项
新安装包 run-LF1aXT 在三引擎各三组配对、共 54 次候选资源探针中通过严格清理检查。核心现代版 raw 134037 → 207875、gzip9 35486 → 58374、Brotli6 32533 → 53326 字节,核心 legacy/ESM 同样超过审查阈值;chapter 三格式均未超过组合阈值。已登记 ENG-PERF-01,由 CORE-22/REVIEW-01 归因、优化和审查剩余开销。
Firefox 第二组 core/chapter 构造耗时分别增加 3/5 ms,WebKit 第三组 chapter 增加 3 ms,其他组未触发。这些是首轮间歇信号,尚不能确认稳定回归;ENG-PERF-02 要求保留样本并继续配对验证,不将单组当作优化或退化结论。最终结果以本任务后续冻结证据为准。
最终收尾运行仍为三引擎各三组配对、54 次候选资源探针通过。Chromium/Firefox 没有计时信号;WebKit 第一组 core/chapter 构造各增加 3 ms,另两组未触发。体积结果与首轮相同,两项风险均保持 open。源码和测试、覆盖率计数、安装包指纹、配对原始记录、两个格式各 114 项资源/生命周期浏览器结果及验证日志哈希一并写入冻结证据,未覆盖首轮报告。
+3 -2
View File
@@ -4,7 +4,7 @@
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 214 项,范围 22 个包及工作区/示例。
状态:todo 156 / doing 0 / blocked 0 / done 58 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
状态:todo 155 / doing 0 / blocked 0 / done 59 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
@@ -81,7 +81,7 @@
| ENG-05 | workspace<br>建立真实浏览器测试服务 | ENG-03, BASE-04, BASE-08 | Playwright projects、本地 Range/失败媒体服务;复用 docs 页面/样本的状态隔离、错误采集与候选资源映射 | Chromium/Firefox/WebKit 的基础播放 smoke 和报告可执行;以媒体状态断言判定通过,区分轻量用例与真实编辑器交互 | M | done |
| ENG-06 | workspace<br>支持按包非交互与 JS/TS 构建 | ENG-02, BASE-05 | build/dev 入口解析、指定包参数、原交互保留 | 三种产物、Less/SVG/worker 和本地 8082 demo 正常;保持 BASE-05 的 AMD 同时写入全局行为及 i18n/legacy 入口 | H | done |
| ENG-07 | workspace<br>建立 tarball 消费与产物检查 | ENG-04, ENG-06 | 隔离 npm 消费 fixtures、API/声明/入口差分 | 不借 workspace 源码通过,能识别缺文件与默认导出变化 | H | done |
| ENG-08 | workspace<br>增加覆盖率、资源与性能报告 | ENG-03, ENG-05, BASE-06 | 覆盖率基线、资源清理断言、性能报告与阈值 | 关键生命周期分支有门槛,报告不靠无意义断言堆数量;将 BASE-06 的同环境多组配对、计时/压缩审查阈值与资源异常分开接入候选,不把历史现象冻结成正常要求 | M | todo |
| ENG-08 | workspace<br>增加覆盖率、资源与性能报告 | ENG-03, ENG-05, BASE-06 | 覆盖率基线、资源清理断言、性能报告与阈值 | 关键生命周期分支有门槛,报告不靠无意义断言堆数量;将 BASE-06 的同环境多组配对、计时/压缩审查阈值与资源异常分开接入候选,不把历史现象冻结成正常要求 | M | done |
| ENG-09 | workspace<br>建立全包依赖影响和文档检查 | ENG-07, DOC-04 | 共享核心/构建影响映射、文档及每任务完成提交的 Git 审计接入;契约-支持版本-测试 ID-命令-候选/报告-任务的覆盖索引 | 核心变化触发必需生态检查;原有 DOC-01 至 04 基线例外明确,后续 done 任务不能缺失独立 commit;计划/已执行/缺证据分开,识别缺少验证归属的公开契约 | M | todo |
| ENG-10 | workspace<br>建立历史失败分级和测试可靠性规则 | ENG-03, ENG-04, ENG-05, ENG-07, BASE-07 | 历史失败 ID/环境/旧版复现/负责修复任务、逐模块门槛、受控等待与 trace/retry 规则 | 不靠全局忽略或无理由 skip 隐藏问题,新增回归阻止交付,设备缺口和偶发失败单独可见;以 risks.json 为统一差异索引;关闭必须有 resolutionEvidence/rationale,已复现、源码事实、未验证分开,登记不等于豁免 | M | done |
@@ -433,6 +433,7 @@
- ENG-05: [记录](changes/2026-09-10-ENG-05-browser-tests.md) [记录](baselines/browser-validation.json)
- ENG-06: [记录](changes/2026-09-10-ENG-06-build-development.md) [记录](build-development.md) [记录](baselines/build-validation.json)
- ENG-07: [记录](changes/2026-09-10-ENG-07-package-consumers.md) [记录](baselines/package-validation.json)
- ENG-08: [记录](coverage-performance.md) [记录](baselines/quality-validation.json) [记录](changes/2026-09-11-ENG-08-quality-reports.md)
- ENG-10: [记录](changes/2026-09-10-ENG-10-test-reliability.md) [记录](test-reliability.md)
- PILOT-01: [记录](changes/2026-09-10-PILOT-01-chapter.md) [记录](baselines/pilot-validation.json)
- CORE-01: [记录](changes/2026-09-10-CORE-01-typed-utils.md) [记录](baselines/core-utils-validation.json)
+10
View File
@@ -1,5 +1,15 @@
# 进度与证据
## 最新完成:ENG-08 覆盖率、资源与性能报告
覆盖率统计核心/chapter 的 224 个运行时文件,明确列出 26 个类型或第三方排除项。首轮发现 file URL 与路径过滤不一致,产生虚假 100% 行覆盖率/零函数分支;已通过原始 V8 数据定位并修复到独立归一化阶段,保留原始文件。真实 esbuild/Vite 映射回归覆盖未执行分支、未导入文件、缺失/过期源码和无效计数。
完整 CI 476 项、249 个生产 TS 严格检查通过;覆盖率四个关键生命周期文件通过原定门槛。新安装包 34 项运行时、5 组旧类型及 8 组精确类型通过,113 个分发/声明/示例产物哈希一致,三个导入检查通过。modern/legacy 的资源、实例和字幕生命周期组合各 114 项通过(每引擎 38 项),没有失败、重试或跳过。
最终三引擎各完成三组配对,54 次候选资源探针严格清理通过;计时/体积仍为 review-required。核心 gzip 增长和间歇构造耗时信号登记为 ENG-PERF-01/02,由 CORE-22/REVIEW-01 处理。新增覆盖率与性能 CI 配置通过 actionlint,但远端尚未运行。见 [冻结证据](baselines/quality-validation.json)、[实施记录](changes/2026-09-11-ENG-08-quality-reports.md) 和 [维护说明](coverage-performance.md)。
ENG-08 done;59 done、155 todo。本任务以独立本地 commit 交付,包含实现、测试、依赖/锁文件、CI、生成产物及文档。下一步 CORE-22 核心总验收,包含性能/体积归因与复核;报告工具通过不是发布放行。没有 push/publish/tag/merge。
## 最新完成:CORE-23 键盘、焦点与可访问名称
默认菜单、原生模式/SSR/字幕检查已完成阶段验证;最终审查另复现并修正设置入口被删除/隐藏/禁用后留下隐藏焦点,以及导航进入隐藏/inert 设置项。四项旧产物回归全部失败,修正后三浏览器设置/集成组合 45 项通过。
+2
View File
@@ -4,6 +4,8 @@
| ID | 状态 / 证据等级 | 条目 | 后续任务 |
| --- | --- | --- | --- |
| ENG-PERF-01 | open / 源码/产物事实 | Candidate core bundles exceed the BASE-06 size review threshold in all three formats | CORE-22, REVIEW-01 |
| ENG-PERF-02 | open / 待取证 | Intermittent constructor timing signals require follow-up paired measurement | CORE-22, REVIEW-01 |
| BASE-LIFE-06 | resolved / 已复现 | Published switch leaves an unhandled rejection and an unsettled promise when resume fails | CORE-09 |
| BASE-LIFE-01 | resolved / 已复现 | Superseded switch resolves along with the latest source | CORE-09 |
| BASE-LIFE-02 | resolved / 已复现 | Switch remains unsettled during the bounded observation after destroy | CORE-09 |
+36
View File
@@ -5,6 +5,42 @@
"updatedAt": "2026-09-11",
"note": "Open means closure evidence is outstanding; source-observed and unverified are not reproduced runtime bugs. A source issue already mitigated in the workspace still requires candidate regression evidence. No accepted-with-scope item is implied by baseline task completion.",
"items": [
{
"id": "ENG-PERF-01",
"title": "Candidate core bundles exceed the BASE-06 size review threshold in all three formats",
"confirmation": "source-observed",
"status": "open",
"owners": [
"CORE-22",
"REVIEW-01"
],
"evidence": [
"refactor/coverage-performance.md",
"refactor/baselines/quality-validation.json",
"refactor/changes/2026-09-11-ENG-08-quality-reports.md"
],
"compatibleResolution": "Attribute the growth to actual modules and build output, remove avoidable overhead while preserving APIs, and document any justified remaining cost against matching published entries.",
"closureCriteria": "Fresh isolated artifacts have reproducible raw/gzip9/Brotli6 results and an explicit size review; do not raise or overwrite the historical threshold to pass.",
"workspaceState": "First ENG-08 modern core measurement: 134037 to 207875 raw bytes, 35486 to 58374 gzip9, 32533 to 53326 Brotli6. Chapter remains below the combined relative/absolute review threshold. This is a review requirement, not a release approval."
},
{
"id": "ENG-PERF-02",
"title": "Intermittent constructor timing signals require follow-up paired measurement",
"confirmation": "unverified",
"status": "open",
"owners": [
"CORE-22",
"REVIEW-01"
],
"evidence": [
"refactor/coverage-performance.md",
"refactor/baselines/quality-validation.json",
"refactor/changes/2026-09-11-ENG-08-quality-reports.md"
],
"compatibleResolution": "Repeat paired measurements on the same environment, distinguish initialization work from host jitter, and optimize only after identifying a reproducible cost.",
"closureCriteria": "Explain repeat-group timing signals with retained samples and source fingerprints; do not infer a regression or improvement from a single group or expand timing allowances.",
"workspaceState": "First ENG-08 run: Firefox group 2 had core/chapter constructor delta 3/5 ms, WebKit group 3 chapter delta 3 ms, versus 2 ms absolute allowance. Other groups did not trigger. Candidate resource checks passed independently. Final run: Chromium/Firefox had no timing signals; WebKit group 1 core/chapter each increased 3 ms, with no signals in the other two groups. The intermittent review remains open."
},
{
"id": "BASE-LIFE-06",
"title": "Published switch leaves an unhandled rejection and an unsettled promise when resume fails",
+5 -2
View File
@@ -12,14 +12,17 @@ export const timingThresholds = {
destroyMs: { relative: 0.25, absoluteMs: 2 },
}
export function validatePerformance(report) {
assert.equal(report.kind, 'performance')
validatePublishedCapture(report, 'performance')
assert.equal(report.capture.media['video.mp4'], hash(fs.readFileSync(path.resolve(refactorDir, '../docs/assets/sample/video.mp4'))))
validatePerformanceMeasurements(report)
}
export function validatePerformanceMeasurements(report) {
assert.equal(report.kind, 'performance')
assert.deepEqual(report.errors, [])
assert.deepEqual(report.unhandled, [])
assert.equal(report.environment.visibility, 'visible')
assert.deepEqual(report.visibilityChanges, [], 'Background timing is not comparable')
assert.equal(report.remainingInstances, 0)
assert.equal(report.capture.media['video.mp4'], hash(fs.readFileSync(path.resolve(refactorDir, '../docs/assets/sample/video.mp4'))))
assert.deepEqual(report.samples.map(({ configuration, round, warmup }) => ({ configuration, round, warmup })), Array.from({ length: 6 }, (_, round) => ['core', 'chapter'].map(configuration => ({ configuration, round, warmup: round === 0 }))).flat())
for (const sample of report.samples) {
for (const key of [...Object.keys(timingThresholds), 'playbackObservedMs']) assert(Number.isFinite(sample[key]) && sample[key] >= 0, `Invalid ${key}`)
+6 -2
View File
@@ -594,11 +594,15 @@
"ENG-05",
"BASE-06"
],
"status": "todo",
"status": "done",
"risk": "M",
"deliverable": "覆盖率基线、资源清理断言、性能报告与阈值",
"acceptance": "关键生命周期分支有门槛,报告不靠无意义断言堆数量;将 BASE-06 的同环境多组配对、计时/压缩审查阈值与资源异常分开接入候选,不把历史现象冻结成正常要求",
"evidence": []
"evidence": [
"coverage-performance.md",
"baselines/quality-validation.json",
"changes/2026-09-11-ENG-08-quality-reports.md"
]
},
{
"id": "ENG-09",
+2
View File
@@ -1,5 +1,7 @@
# 测试与验收
核心/chapter 的 Node TS 覆盖率使用 `yarn test:coverage`。源映射防伪验证、关键生命周期门槛、报告位置及资源/性能实施状态见 [覆盖率与性能维护说明](coverage-performance.md)。
## 测试层次
浏览器验收采用连接的 @Chrome 交互检查与仓库自动回归相结合;具体操作断言、证据范围和真机边界见 [多轮复盘与 npm 准入](release-reviews.md)。浏览器已连接不代表播放器用例已通过。