Files
aurora-admin/TESTING.md
T
aurora-admin 6fec4ba6f8 v1.3.0: 修复验收链路(iframe 真实渲染+跨帧断言)、基座焦点环、契约第二批 15 个
回归通过率此前不可信:run-tests.ps1 抽取演示页 body 时剥离全部 <script>,
而 79 个 H5 演示页的 DOM 全由内联脚本渲染,且测试页从未引用 frameworks/<组件>.css
—— 断言跑在空 DOM + 无组件样式上,v1.2.0 的 75.1% 属结构性误报。

Fixed — 验收链路
- 测试页改为 iframe 加载真实演示页(_template.html),_runtime.js 跨帧在真实
  渲染结果上断言:帧内 getComputedStyle/styleSheets/outerHTML,用例自动标注 +
  帧内描边,结果 postMessage 上报
- 标注改为容器下钻(.row/.demo-block → 首个含 ≥2 有效子元素的容器,最多 6 层)
- 新增 N/A 语义:静态组件键盘/ARIA 记 skip 而非失败;对比度与 token 检查限定
  在被测组件区,页头文档文字不计
- 通过率分母改为 pass/(pass+fail),tools/run-regression.mjs 与收集器同口径

Added — 设计系统
- 基座 :focus-visible 统一焦点环(colors_and_type.css)。--au-color-focus-ring
  此前只定义未消费,79 个组件样式仅 20 个自带 focus 规则 —— 一次性消除 66 页失败
- tests/_collect.html:零依赖浏览器批量回归收集器(并发 iframe + 汇总)
- tests/_index_template.html:测试总览页模板外置,读数来自 data.json

Added — 契约第二批(展示类 15 个)
- tree/collapse/calendar/carousel/imagepreview/qrcode/countdown/watermark/
  cardlist/treetable/timelinelist/steplist/chartpanel/dashboardcard/employeecard
- 逐份从规格原文(组件2/4/7/9.txt)提炼,含 dims/variants/anatomy/structure/
  usageHints/doNotInvent/unknowns;契约化 21 → 36/79

Changed
- run-tests.ps1 重写:删除失效的快照抽取(占位符替换早已不匹配模板),改生成
  iframe 版测试页;输出 WriteAllText 无 BOM;保持 ASCII-only,中文移入 UTF-8 模板
- 回归基线:960 断言 / 794 通过 / 85.1% / 11 页全通过 / N/A 27
- CHANGELOG/TESTING/改造清单同步;测试总览页与首页通过率联动

验证:浏览器全量 79 页收集器跑通两次,基线一致;详情页契约章节
(含 doNotInvent/unknowns)、chip、首页「通过率 85.1%」、changelog v1.3.0 实测通过
2026-09-10 21:19:09 +08:00

123 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 测试说明
Aurora Admin 组件库的测试设计:**零依赖、可视化、可机读**。每个组件都有一份独立的测试页 `tests/<slug>.html`,加上 `tests/index.html` 总览入口。
## headless 回归(v1.2.0 起,v1.3.0 修正口径)
```bash
node site/dev-server.js # 先起站
node tools/run-regression.mjs # 需 npm i playwright;输出 tests/report.json + report-junit.xml
```
无 playwright 的机器用浏览器跑法(零依赖):打开 `tests/_collect.html`,它把 79 个测试页并发装入同源 iframe,汇总后写入 `window.__aaCollectResult`(同 `report.json` 结构),从控制台取出落盘即可。
- `tests/report.json` 是首页「测试通过率」的数据源;无报告时首页静默隐藏该数字。
- 当前基线:960 条断言,通过率 **85.1%**(N/A 27)、11 页全通过。
- **通过率 = pass / (pass + fail)**,N/A(静态组件无交互面等)不计入分母,避免拉低数值。
- 失败项是真实缺口,不是 runner 误报:状态覆盖(states)45、对比度 35、ARIA 33、键盘可达 15、硬编码 hex 9、变体 2。
### 断言为什么跑在 iframe 里
79 个 H5 演示页的 DOM **全部由内联脚本渲染**(body 只有 `<div id="app"></div>` + `<script>render()</script>`)。v1.2.0 曾尝试把演示页 body 抽成静态快照,但剥离 `<script>` 后 DOM 为空,且测试页未引用 `frameworks/<组件>.css`——断言在空 DOM 上必然大面积失败,当时的 75.1% 是结构性误报。
因此测试页 `<iframe id="snapshot-frame" src="../frameworks/<组件>.html">` 直载真实演示页:CSS 与脚本真实执行,`_runtime.js` 跨帧读取 `contentDocument` 执行断言(同源可直读),用例节点在帧内自动标注 `data-assert` 并描边可视化,结果 `postMessage` 给父页与收集器。
用例标注规则:优先 `.row / .demo-block / .demo-row` 的子元素;否则从被测范围向下寻找「首个含 ≥2 个有效子元素的容器」(最多 6 层)。页头文档文字(h1 / .sub)不计为用例。
- 注意:重建 data.js 后浏览器需 Ctrl+F5;重建测试页后无需额外处理(标注在运行期完成)。
## 测试矩阵(每个组件都跑这 8 项)
| # | 维度 | 说明 |
|---|---|---|
| 1 | 默认态渲染 | 核心节点齐全(容器 + 标签 + 图标位等) |
| 2 | 尺寸/类型变体 | 大/中/小;主/次/文字/链接/危险等(≥2 用例) |
| 3 | 状态覆盖 | default / hover / active / focus / disabled / loading 至少出现 1 个状态类(或 ≥3 用例) |
| 4 | 可见用例 | ≥1 个用例在默认态可见(默认隐藏的交互后可见者记 skip) |
| 5 | 键盘可达 | 可聚焦元素具备 tabindex 或原生 button/a;静态组件记 N/A |
| 6 | 焦点环可视 | `:focus-visible` 描边规则存在(基座 `colors_and_type.css` 已统一提供) |
| 7 | ARIA 属性 | 交互节点具备 role / aria-*;静态组件记 N/A |
| 8 | 对比度 | 被测组件区文本 ≥ 4.5:1(大字号 ≥ 3:1),页头文档文字不计 |
| 9 | token 一致性 | 用例区内联 style 不出现硬编码 hex 颜色 |
## 断言协议
每个测试用例在 DOM 上加两个属性(测试页由 `_runtime.js` 运行期标注,演示页源文件不必手写):
```html
<button class="btn btn-primary" data-assert="variant-1" data-status="pass">主按钮</button>
<button class="btn btn-primary" data-assert="variant-2" data-status="skip" disabled>禁用态</button>
```
- `data-assert`:唯一断言 ID(`variant-<n>`,运行期自动标注)
- `data-status`:当前结果(`pass` / `fail` / `skip`)
「运行断言」会执行两类检查并把 `data-status` 写回帧内节点:① 用例可见性(默认态可见记 pass,交互后才出现的记 skip);② 通用测试矩阵 9 项。失败项写 `localStorage[aa-test-log]`,可导出。
## 如何跑测试
### 方式一:浏览器手动
1. 打开 `tests/index.html`
2. 点击任一组件 → 进入该组件的测试页
3. 观察渲染快照与断言列表
4. 点击「运行断言」得到 PASS/FAIL
5. 顶部「导出日志」按钮下载 JSON
### 方式二:自动化(Playwright)
现成 runner 见上节 `tools/run-regression.mjs`。要点是断言在 iframe 演示页加载后自动执行,需等汇总区出现结果再读取:
```javascript
const page = await ctx.newPage();
await page.goto('http://127.0.0.1:3311/tests/button.html');
await page.waitForFunction(() => document.getElementById('sum-total')?.textContent !== '总数 0');
const r = await page.evaluate(() => ({
total: Number(document.getElementById('sum-total').textContent.replace(/\D/g, '')),
fail: [...document.querySelectorAll('#result-list .t-row .t-pill.fail')].length
}));
```
## 重新生成测试目录
```powershell
powershell -File run-tests.ps1
```
按 `components/index.json` 的 79 项生成 `tests/<slug>.html`(iframe 版)与 `tests/index.html`,并报告缺失的演示页。模板在 `tests/_template.html`(单页)与 `tests/_index_template.html`(总览页)——改测试页结构请改模板后重跑,不要手改生成的 `<slug>.html`。
脚本保持 ASCII-only(PS5.1 按 ANSI 读取无 BOM 文件,非 ASCII 字面量会被损坏);中文文案一律放在 UTF-8 模板里。输出用 `WriteAllText` 无 BOM 写出。
## 日志格式
`localStorage[aa-test-log]` JSON 结构:
```json
{
"ts": 1757232000000,
"slug": "button",
"page": "tests/button.html",
"assertions": [
{ "id": "btn-primary-default", "status": "pass", "durationMs": 12 },
{ "id": "btn-disabled", "status": "pass", "durationMs": 8 }
],
"errors": []
}
```
控制台输入 `aaLogger.export('test')` 导出当前所有日志。
## 与文档站的关系
- 文档站 `site/app.js` 详情页有「测试页」按钮直达 `tests/<slug>.html`
- 测试页头部有「← 返回文档站」按钮回 `site/index.html`
- 两者共用 `colors_and_type.css`,主题色随主题切换实时同步
## 不在本轮范围
- React 单元测试(Jest / Vitest)
- 视觉回归(像素对比)
- E2E 流程测试(点击 → 跳转)
这些会在 v1.2.0 之后考虑。