NG-ZORRO 测试评审指南:用公共契约思维判定测试的 Keep / Rewrite / Remove

发布时间:2026/9/25 1:31:00
NG-ZORRO 测试评审指南:用公共契约思维判定测试的 Keep / Rewrite / Remove
UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载本指南以 .agents/skills/test-review/SKILL.md 为骨架面向 NG-ZORROng-zorro-antd组件库的贡献者与维护者讲解如何评审仓库中已有测试的价值判断某条测试应当保留Keep、重写Rewrite还是删除Remove。读完本篇你将掌握以公共契约public contract为核心的评审方法——用可观察的外部行为表述测试目标、识别与实现细节耦合的断言、查重已有规范并能在不运行测试、不修改生产代码的前提下完成一次结构化的测试评审。评审的本质这是一次审阅不是写测试该 Skill 开篇就划定了边界测试评审是一项 review 任务不是新增测试或修改生产代码的请求。评审者的职责是判断这条测试是否守护了公共契约而不是动手补测试、重构实现或改断言。评审时可以也应该查阅以下材料来形成判断相关的 issue测试要守护的回归场景组件文档与 democomponents 目录下各组件自带的doc/与demo/组件实现源码邻近的 Vitest 规范文件*.spec.ts同时要注意除非用户要求执行证据否则不要运行测试。也就是说评审结论应建立在代码阅读与契约推导之上而非依赖跑测试的输出来猜测试是否有价值。第一步用可观察的措辞陈述被守护的契约评审的核心产出之一是把这条测试声称守护的契约翻译成可观察的表述给定某条件given a condition使用者应当观察到某结果a consumer should observe a result。这种 given → observe 的句式有严格的价值来源要求一个有意义的期望值必须有独立来源例如已报告的回归reported regression公共 API 定义public API文档化的行为documented behavior无障碍语义accessibility semantics浏览器原生行为browser behavior用户可见的结果user-visible result换句话说期望值不能从实现里现抄。如果一条测试的期望值只能从被测代码本身推导出来它就缺乏独立基准容易滑向证明代码存在的无效测试。仓库中的可观察契约示例NG-ZORRO 的规范文件大量体现了这种可观察结果的写法。例如 checkbox.spec.ts 中的 a11y 用例it(should click input a11y correct, async () { const inputElement checkbox.nativeElement.querySelector(input); ... inputElement.checked true; inputElement.dispatchEvent(new Event(change, { bubbles: true })); await stabilize(fixture); expect(testComponent.checked()).toBe(true); expect(inputElement.checked).toBe(true); expect(testComponent.modelChange).toHaveBeenCalledTimes(1); });这里守护的是用户通过原生 checkbox 输入触发的变更会反映到组件模型并发出输出事件——输入是浏览器原生事件输出是公开的modelChange期望值完全独立于实现细节。再看 alert-marquee.spec.ts 中的无障碍断言it(should set aria-hiddentrue on the second track for accessibility, () { expect(tracks[1].getAttribute(aria-hidden)).toBe(true); });这条测试守护的契约是重复轨道对辅助技术隐藏——来源是无障碍语义ARIA属于独立规范而非实现偶然产物。第二步优先断言外部可观察层警惕实现耦合断言Skill 明确给出了断言层的优先级优先断言渲染后的 DOM、ARIA 语义、发射的输出事件、公共 API 行为和交互结果。相应地以下类型的断言应被视作与实现耦合implementation-coupled除非该测试存在独立的视觉或兼容性契约私有辅助函数的断言private helpers中间状态的断言intermediate state临时 class 的断言temporary classesCSS 自定义属性的断言CSS custom properties孤立样式声明的断言isolated style declarations举例来说checkbox.spec.ts 中断言ant-checkbox-wrapper、ant-checkbox、ant-checkbox-input、ant-checkbox-inner等 class 是否存在的用例需要结合契约背景判断如果这些 class 是主题系统、样式定制或视觉契约的一部分NG-ZORRO 的样式体系见 components/style 目录它们就有独立的视觉/兼容契约如果只是实现偶然引入的临时标记则属于实现耦合。segmented.spec.ts 中大量断言nz-selected、nz-disabled等属性渲染与键盘方向键行为、thumb 动画状态的用例则分别对应键盘可操作性与选中态这一可观察契约以及动画视觉结果这一独立契约——两者都有外部可观察性。判断技巧问自己这条断言若失败使用者真的会看到问题吗若失败只会暴露内部实现细节而用户界面与交互毫无变化这条断言很可能就是实现耦合的。第三步查重——已有规范是否已守护同一条件在给出结论前必须检查现有 spec 是否已经守护了相同的条件。这需要搜索同一组件目录下的全部*.spec.ts与相邻组件的规范对照 issue、文档与 demo确认同一回归场景是否已被另一条测试覆盖特别留意跨文件的重复守护NG-ZORRO 的测试运行环境是共享的见下文环境事实重复覆盖本身不是罪但若两条测试守护的契约完全相同、断言层也相同就应合并或删除冗余。第四步给出分类结论——Keep / Rewrite / Remove每一条被评审的测试都应归入三类之一且先亮结论再给最有力的几条理由分类判定标准典型场景Keep保留独立指定independently specified、外部可观察externally observable、不重复non-duplicative守护已报告回归、公共 API 行为、ARIA 语义、浏览器原生行为的测试Rewrite重写想守护的回归本身是有效的但断言与实现耦合例如想验证禁用状态下不可选却断言了某个内部状态字段或临时 classRemove删除期望值从同一实现推导而来、只证明存在、或与已有契约重复例如断言私有字段初值、断言内部 flag 翻转、与已有测试守护同一条件此外Skill 特别说明只有在被要求时才给出重写方向rewrite direction。默认输出应聚焦分类与理由不要越界给出完整重写方案。结合仓库事实测试评审发生的环境为了让评审结论更贴合 NG-ZORRO 的实际这里补充几个仓库级的测试基础设施事实评审时理解它们有助于判断重复与耦合测试运行器是 Vitest。测试脚本见 package.jsontest/test:watch通过 Nx 运行ng-zorro-antd-lib测试配置见 vitest.config.mjs。串行且隔离的执行模型。vitest.config.mjs 中fileParallelism: false与isolate: true的注释说明部分历史遗留 spec 仍通过 overlay、viewport mock、timers 和原型 spy 共享浏览器级状态因此文件串行执行、逐文件隔离直到这些 spec 不再依赖全局浏览器状态。共享的全局环境重置。vitest-setup.ts 在每个用例前后统一处理beforeEach配置provideZonelessChangeDetection()与provideNzDateFnsAdapter()afterEach清理 fake timers、恢复 mockvi.restoreAllMocks()、复位视口与 rAF、清理 body 中遗留的 overlay 与测试根节点。这意味着评审时若看到某测试依赖另一个 spec 留下的全局状态它很可能在隔离环境下并不稳定——这类测试的契约表述往往也有问题。可用的测试辅助工具。components/core/testing 提供了testDirectionality、updateNonSignalsInput、stabilize见 zoneless-helpers.ts、dispatch-events、type-in-element、mock-ng-zone等工具checkbox.spec.ts 中的testDirectionality, updateNonSignalsInput即来自该目录。评审中若发现测试用手写的setTimeout/detectChanges序列替代这些稳定化工具可作为重写方向的候选理由。覆盖率报告。coverage配置输出 html / text-summary / lcovonly / cobertura 到coverage-report见 vitest.config.mjs但要注意覆盖率是度量指标不是测试价值的来源——这行没被覆盖不等于该补一条实现耦合的测试。一个完整的评审示例方法论演示假设你在components/xxx/xxx.spec.ts中评审这样一条测试示意it(should disable the item, () { component.disabledState true; expect(component.isDisabledInternal).toBe(true); });按本文方法逐步评审表述契约该测试想守护的契约是当nzDisabled为 true 时使用者不能通过交互选中该项——这是一个有效的用户可见契约可观察结果应为点击后nzSelect/modelChange不触发或渲染出 disabled 语义如aria-disabled。检查断言层isDisabledInternal是内部字段断言属于实现耦合应优先断言aria-disabled属性、点击后的输出事件或键盘不可达性。查重搜索同组件 spec确认是否已有测试守护disabled 下点击不 emit这一条件。分类若已有覆盖 →Remove重复若没有 →Rewrite回归有效、断言耦合并在被要求时给出改为断言输出事件/ARIA 的方向。评审清单可直接复用该测试守护的契约能否用 given → observe 表述期望值是否有独立来源回归、公共 API、文档、ARIA、浏览器行为、用户可见结果断言是否落在渲染 DOM / ARIA / 输出事件 / 公共 API / 交互结果上是否存在对私有 helper、中间状态、临时 class、CSS 自定义属性、孤立样式声明的断言同一条件是否已被现有 spec 守护分类是否清晰Keep / Rewrite / Remove理由是否只保留了最强的几条是否只在被要求时才给出重写方向掌握这套方法后你可以在 NG-ZORRO 的任意组件规范文件如 components/table 下数十个 spec、components/select 的规范集上执行结构化评审先分类、再给理由、必要时给方向让每个测试都明确回答它守护了什么用户看得见的契约。赞分享UI组件前端【免费下载链接】ng-zorro-antdAngular UI Component Library based on Ant Design项目地址https://gitcode.com/gh_mirrors/ng/ng-zorro-antd点击查看免费下载相关推荐5分钟上手PowerToys文本提取器一个能从屏幕任意位置提取文字的OCR工具5分钟上手PowerToys文本提取器一个能从屏幕任意位置提取文字的OCR工具 PowerToys文本提取器是微软开源套件PowerToys中的一个模块它基桌面应用开发工具用黑盒契约测试守护 Manifest Gateway读懂 contracts/gateway 的公共 API 稳定性保障用黑盒契约测试守护 Manifest Gateway读懂 contracts/gateway 的公共 API 稳定性保障 Manifest 是一个开源 LLMAI 应用LLMOps可观测性ppf-contact-solver高级技巧5个优化接触检测性能的实用方法ppf contact solver高级技巧5个优化接触检测性能的实用方法 ppf contact solver 是一款强大的物理模拟接触求解器专门用于处理物理引擎高性能计算上一篇SecHex-Spoofy终极指南深度解析Windows硬件身份伪装技术实战应用下一篇Bevy 引擎性能剖析完整指南CPU 运行时、GPU 瓶颈与编译期开销的诊断方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考