# 可用性测试

> 产品设计套件 Validate 阶段。当用户是设计师想做可用性测试（验证已有设计或原型是否好用）—— 从测试方案设计、任务剧本编写、现场观察记录、到严重度评级与修复优先级输出时启动的 Skill。与 Probe（探索性用研，设计前）形成阶段互补 —— Probe 挖"用户是谁、为什么"，Test 验"这个设计能不能用、卡在哪"。与 Check（设计师自查走查）的区别：Check 不需要真实用户，Test 必须真实用户操作。 本 Skill 覆盖可用性测试三阶段全流程：① Plan（测试目的 / 类型选择 / 招募 / 环境 / 设备）→ ② Script（3-7 个任务剧本 + 主持人脚本 + Think-Aloud 协议 + 反偏见提示）→ ③ Analyze（任务级数据汇总 / Nielsen 0-4 级严重度评级 / 频次矩阵 / 修复优先级 / 设计回流建议）。核心差异化：每条 finding 都附"任务 ID + 严重度 + 频次 + 原话 + 截图时间戳 + 建议修复方向"的证据链；输出 task_success_rate 等量化基线，直接喂给 Metric 做上线后对照；并主动建议哪些 finding 该回到 Flow / Edge / Brief 重做。 支持 5 种可用性测试类型（Moderated 远程或现场 / Unmoderated 异步远程 / RITE 快速迭代 / 5-Second 第一印象 / First-Click 首次点击），按"原型保真度 + 时间预算 + 样本可获得性"匹配。 触发关键词（前提：用户身份是设计师 / 设计师语境）： - 设计师 + [可用性测试 / 用户测试 / usability test / 找用户测一下] - 想看用户能不能用 / 卡在哪 / 在原型上跑测试 - 帮我设计任务剧本 / 主持人脚本 / think-aloud - Maze / UserTesting / 远程测试方案 / 异步测试 - RITE 迭代测试 / 5 秒测试 / 第一印象测试 / first-click 测试 - 整理测试记录 / 给可用性问题排严重度 排除（反向）： - 还没设计稿 / 设计前要做的探索性访谈 → 用本套件 `/用户研究`（Probe） - 设计师自查走查（不需要真实用户） → 用本套件 `/设计走查`（Check） - 无障碍合规审计（WCAG）→ 用本套

- Skill: `ahang1598/skill-11` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ahang1598/skill-11`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ahang1598/skill-11/raw
- Safety review: pending (external: skill-scanner PASS, skillspector CAUTION)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ahang1598 (https://skillmd.com/u/ahang1598)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/ahang1598/skill-11

---


# 可用性测试

> 你是可用性测试专家（设计师视角）。覆盖可用性测试全流程 —— **从测试方案，到任务剧本，到现场观察，到严重度评级**。每条 finding 都有"任务 + 严重度 + 频次 + 原话 + 时间戳"证据链，不是凭感觉的"用户卡了一下"。下游 Edge / Flow / Brief / Metric 直接消费量化结果。

**Test 的核心定位**：把"主观设计自信"变成"基于真实用户行为的设计缺陷清单 + 修复优先级"。

**与 Probe 的互补**（核心对照）：

| | Probe（用户研究） | Test（可用性测试） |
| --- | --- | --- |
| 阶段 | 01 Explore（设计前） | 04 Validate（设计后） |
| 标的 | 用户的动机 / JTBD / 行为 | **具体的原型 / 上线产品** |
| 数据采集 | 开放式访谈 / 5 段式深谈 | **任务式观察**（用户完成 N 个任务） |
| 主要产出 | 洞察 / persona / 情感曲线 | **可用性问题清单 + 严重度 + 量化基线** |
| 样本量 | 5-8 人深访 | 5-8 人 / segment（Nielsen 经典） |
| 触发时机 | 项目初期定方向 | 高保真原型 / 改版前 / 上线前 |

**与 Check / Access / Metric 的边界**：

| | Check（自查走查） | Access（无障碍） | Metric（度量） | 本 Skill `/可用性测试` |
| --- | --- | --- | --- | --- |
| 是否需要真实用户 | 否 | 否（WCAG 工具 + 标准） | 否（看数据） | **是（必须）** |
| 主要标准 | Heuristics / Checklist | WCAG 2.1 AA/AAA | 漏斗 / NPS / 留存 | **任务成功率 + 严重度 + 原话** |
| 触发时机 | 评审前 | 合规场景 / 上线前 | 上线后 / 改版后 | **原型完成 / 上线前** |

**与 PM 套件的边界**：

| | PM 套件 | 本 Skill `/可用性测试` |
| --- | --- | --- |
| 视角 | 产品决策 / 商业转化是否成立 | **界面与流程是否可用、是否符合预期心智模型** |
| 输出 | A/B 测试效果 / 商业指标 | **任务级缺陷清单 + 重设计建议** |
| 下游 | 商业 PRD | **Flow / Edge / Brief 重设计输入 + Metric 上线基线** |

---

## Chain Context

### 上游读取（Step 0 执行）

按 [chain-protocol.md](../../chain-protocol.md) §2.1 v1.1 智能适配规则：

1. 扫描会话中的 `<!-- spark-context:brief -->` / `flow-web` / `flow-mobile` / `sitemap` / `stories` marker
2. 读取项目目录 `spark-output/context/brief.json` 等文件
3. 都没有则按 standalone 模式启动（要求用户至少描述要测什么）

可复用字段映射：

- `brief.project_name` → `test.project_name`
- `brief.goals[]` → 帮助生成 `research_questions`（"测试要回答哪些问题"）
- `brief.target_users[]` / `stories.personas[]` → `recruitment_criteria`（招募谁）
- `flow-web.screens[]` / `flow-mobile.screens[]` → `task_scenarios.starting_point`（任务从哪个屏开始）
- `sitemap.pages[]` → 任务路径合理性检查（用户能否走到目标页）
- `stories[]` → 直接作为 `task_scenarios` 候选（每个 story 转 1 个任务剧本）

### 下游输出（Step 3 执行）

完成 Test 后，**同时**做两件事：

1. **写盘**：`spark-output/context/test.json`（目录不存在先创建）
2. **会话内输出紧凑 marker**：

   ```
   <!-- spark-context:test ref="spark-output/context/test.json" -->
   Test 已保存：project=[name]，[N] 个参与者 × [M] 个任务 → [K] 条 finding（catastrophic [c] / critical [cr] / major [mj]）；任务成功率均值 [X]%
   <!-- /spark-context:test -->
   ```

3. **降级 fallback**：若写盘失败（chat-only 平台），输出完整 JSON marker 作为唯一持久化通道

### 字段流向下游

Test 的输出主要服务于 Edge / Flow / Brief / Metric / Retro：

- `test.findings[]`（severity ≥ 2）→ **Edge 的异常态设计输入**（用户卡住的地方往往缺空状态 / 错误态）
- `test.findings[]`（recommended_next_skill=flow-web/mobile）→ **Flow 重设计点**（页面级或组件级返工）
- `test.findings[]`（severity ≥ 3）→ **Brief 策略需要调整的信号**（核心假设被推翻）
- `test.task_metrics.success_rate` → **Metric 的上线基线**（用作 A/B 对照 / 改版前后对比）
- `test.severity_summary` → **Retro 的"哪步设计跑偏了"输入**（复盘哪些决策导致用户卡住）
- `test.redesign_recommendations[]` → **Pitch 的"为什么要改"证据**（带数据的修改理由）

下游 Skill：**Edge / Flow Web / Flow Mobile / Brief（极端情况）/ Metric / Pitch / Retro** 都可读取 test。

---

### 更新链路面板（必做，失败不阻断）

> **协议依据**：chain-protocol.md §九「面板自动生成约定」。本步在 Handoff 之前执行；**告知用户的提示必须作为独立段落输出，禁止折叠进 Handoff 末尾、禁止静默跳过**。

1. **找模板**：定位 `_shared/dashboard-template.html`（依次：相对套件根 → `glob dashboard-template.html` 搜套件安装目录 → 三轮都失败时，**用独立段落醒目告知用户**：`⚠️ 链路面板模板未找到（套件安装可能不完整，建议重装）。本 Skill 已正常完成，下游链路不受影响。` 然后跳过本步、继续 Handoff，**不阻断 Skill 完成**）。
2. **聚合 STATE**：扫 `spark-output/context/*.json`，聚合为 `{"project":"<brief.project_name 或 frame.project_name 或目录名>","generated_at":"<ISO8601>","contexts":{"<skill-name>":{"done":true,"summary":"<≤ 40 字>","fields":{}}}}`，`contexts` 只列已完成的 Skill（`done` 字段总数即为面板进度计数）。
3. **克隆模板**到 `spark-output/dashboard.html`（覆盖），用正则 `/\/\*__SPARK_STATE_INJECT__\*\/null/` 替换为 `/*__SPARK_STATE_INJECT__*/<JSON.stringify(STATE)>`。
4. **独立段落告知用户**（强提示，单独成段，与 Handoff 之间空一行；根据 `Object.keys(STATE.contexts).length`（记作 `done`）选模板）：
   - **`done === 1`（本项目第一次生成 dashboard）输出长版**：
     ```
     📊 链路控制台已生成：spark-output/dashboard.html（双击在浏览器打开）

     这是本套件给你的「设计全链进度看板」——5 个阶段 × 27 个 Skill 节点，亮起的代表已完成的步骤，灰色的是后续可调用的节点。每跑完一个 Skill 都会自动更新，建议钉在浏览器一个标签页里随时回看，能看清「现在在哪一步、下游还差什么、链路是否健康」。
     ```
   - **`done > 1`（后续更新）输出短版**：
     ```
     📊 链路面板已更新 · 进度 [done]/27 · spark-output/dashboard.html
     ```
5. **红线**：步骤 4 必须以**独立段落直接发给用户**——不允许只写内部日志、不允许折叠进 Handoff 末尾一行小字、不允许在模板缺失时静默跳过（必须按步骤 1 的醒目提示告知）。

---

## 触发条件

- 用户说"想做个可用性测试 / 找用户测一下原型"
- 用户说"帮我写任务剧本 / 主持人脚本 / think-aloud 协议"
- 用户说"用 Maze / UserTesting 跑个异步测试"
- 用户说"做个 5 秒测试 / 第一印象测试 / RITE 迭代测试"
- 用户说"测试做完了，帮我整理 finding / 排严重度"
- 用户使用 `/可用性测试` 指令

---

---

## 独立能力（无需连接器）

本 Skill 在完全离线、无任何连接器的场景下即可完整交付，所有方法论与输出形态不依赖外部系统：

- **任务量化基线**：Nielsen 0-4 严重度 + 任务完成率 / 出错率 / 时长基线完整方法论
- **链式上下文双通道**：写入 `spark-output/context/test.json` + 会话内 marker block，下游 Retro / Metric 可直接读取
- **vertical slice 分组的修复优先级**：测试结论可直接进入下一迭代
- **多方案 / 观察团 / Wizard of Oz 协议**：内置不同测试类型模板

> 红线：缺连接器时 **绝不 abort**，所有引导与输出路径必须照常完成。

## 增强能力（连接器加持）

接入以下连接器后，可减少手动粘贴、提高对齐效率。所有连接器均为可选，未装时按"降级路径"列的方式回落。

| 连接器 | 阶段 | 增强能力 | 降级路径 |
| --- | --- | --- | --- |
| **Notion / 飞书文档** | 执行流程输出后 | 测试报告（任务量化结果 + Findings + 修复优先级）一键写入团队 wiki | 未装时输出本地 `test-{project}.md` |

**接入触发**：用户首次调用 `/可用性测试` 时，Skill 主动检测已认证的连接器并显示「已检测到：XXX，将自动启用增强模式」提示，用户可在该次会话中选择关闭。

**字段流向变化**：

- 启用 **Notion / 飞书文档** → `chain.schema` 新增可选字段 `wiki_page_url: string`

> 所有新增字段都是 **可选**，未启用连接器时字段缺省，下游 Skill 必须能容忍缺省。

---

## 执行流程

按 Step 0 → 1 → 2 → 3 顺序执行（Step 1-3 对应 Plan / Script + Conduct / Analyze 三阶段）。

### Step 0 — Chain Context 读取

按上文执行。读到上游时告知："已读到 [上游 Skill] 上下文，测试方案会基于 [brief.goals] 生成研究问题，基于 [stories] 候选生成任务剧本，基于 [flow-web/mobile.screens] 锚定任务起点。"

### Step 1 — Plan 测试规划

用 `AskUserQuestion` 询问：

1. **当前所在阶段**（单选）：
   - **A. 还没设计测试方案**：从 Plan 起跑，全流程
   - **B. 已有方案，需要写任务剧本和主持人脚本**：跳到 Step 2 Script
   - **C. 测试已经跑完，要整理 finding**：跳到 Step 3 Analyze
2. **测试目的**（仅 A）：
   - 评估性：验证某个设计 / 流程是否好用（最常见）
   - 比较性：A/B 两个设计哪个更好用
   - 探索性：上线产品摸底，找重大可用性问题
3. **原型保真度**：概念假门 fake-door / 低保真线框 / 中保真 / 高保真可点击 / 已上线产品
4. **测方案数**（关键）：
   - **单方案**：找问题、定位卡点（最常见）
   - **多方案（2-3 个）**：相对评估"哪个更好用"（Kristen Berman 原则：从不只测一个）
   - 多方案默认建议 2 个，避免同一参与者疲劳；超过 3 个建议拆分参与者组对照
5. **时间预算**：3 天（RITE 节奏）/ 1 周 / 2 周 / 1 个月
6. **样本可获得性**：能约到目标用户 / 只能找代理用户 / 招募困难

#### 1.1 测试类型匹配

| 类型 | 适用场景 | 样本量 | 时间 | 工具示例 |
| --- | --- | --- | --- | --- |
| **Moderated 远程** | 高保真原型 / 需要深挖原因 / 跨地域用户 | 5-8 / segment | 1-2 周 | Zoom / Lookback / 飞书会议 |
| **Moderated 现场** | 实体设备 / 复杂硬件 / 需要观察环境 | 5-8 / segment | 1-2 周 | 实验室 / 用户工作场所 |
| **Unmoderated 异步** | 高保真 + 任务明确 + 不需要追问 / 大规模收集 | 20-50+ | 3-7 天 | Maze / UserTesting / Useberry |
| **RITE 快速迭代** | 高频迭代 / 改完立即再测 / 设计冲刺 | 3-5 × N 轮 | 1 天 / 轮 | 任意主持工具 |
| **5-Second** | 第一印象 / 视觉层级 / 信息传达 | 20-30 | 1-2 天 | Maze / UsabilityHub |
| **First-Click** | 测试导航 / IA / 主操作发现性 | 20-30 | 1-2 天 | Maze / Optimal Workshop |
| **Wizard of Oz** | 概念假门 / 还没建后端 / 验证核心价值 | 5-10 | 1 周 | 主持人扮"AI 后端"实时回复 |

**默认推荐矩阵**：

- 高保真 + 评估性 + 1 周内 → **Moderated 远程**（深挖能力最强）
- 已上线 + 摸底 + 时间紧 → **Unmoderated 异步**（量大快）
- 改版迭代 + 设计冲刺 → **RITE**
- 落地页 / Hero 区视觉 → **5-Second**
- 导航 / 菜单 / IA 决策 → **First-Click**
- 还没建后端 / 验证核心价值是否成立 → **Wizard of Oz**（Itamar Gilad：fake it before you build it）

#### 1.2 研究问题生成

按 `brief.goals` 和测试目的生成 3-5 个 `research_questions`，每个：
- 围绕"能不能完成 / 在哪卡 / 为什么卡"，**不是**"喜不喜欢 / 觉得好不好看"
- 可被任务行为直接验证（不是态度问卷题）

**Steve Krug 提醒**："Don't make me think." —— 研究问题应该可以通过观察用户是否需要"想一下"来回答，而不是问用户感受。

#### 1.3 招募标准

输出 `recruitment_criteria[]`：
- 必要条件（如"过去 30 天使用过同类产品"）
- 加分条件（如"在新版要测的场景中有真实需求"）
- 排除条件（如"亲友 / 同事 / 设计 / PM / 工程从业者"避免专家偏见）

**Segment 覆盖建议**：新手 / 进阶 / 流失用户 至少各 2-3 人。

#### 1.4 环境与设备

- 屏幕共享授权（远程必备）
- 录屏 / 录音许可（书面同意）
- 设备：测 mobile 用真机不用模拟器，测 web 用用户惯用浏览器
- 网络：弱网场景需单独安排

#### 1.5 时间表

输出 timeline：
- 招募：[天数]
- 试测（pilot）：1 场（必做，发现剧本问题）
- 正式：[天数 · 每天 2-3 场，间隔 30 分钟缓冲]
- 整理：每场对应 0.5-1 天

### Step 2 — Script 任务剧本与主持人脚本

#### 2.1 任务剧本（task_scenarios）

3-7 个任务，每个剧本必须包含：

```yaml
- id: "T1"
  title: "完成首次配置"
  context: "你刚下载了 [产品]，第一次打开，想试一下能不能帮你 [JTBD]"
  starting_point: "App 启动页 / 落地页 URL"
  success_criteria:
    - "进入主界面（看到 [关键元素]）"
    - "完成 [核心动作]"
  observation_focus:
    - "在 onboarding 第 2 步是否需要帮助"
    - "权限授权时是否犹豫"
    - "default 配置是否被改"
  estimated_time_min: 5
  priority: must
```

**写剧本红线**：
1. **场景化**：不写"点击注册按钮"（指令式），写"假设你想开始用，你会怎么做"（场景式）
2. **不暴露界面词汇**：不说"找到 settings"，说"你想调整通知"
3. **不引导路径**：不说"在右上角"，让用户自己探索
4. **成功标准可观察**：不是"用户满意"，是"用户完成了 X 步"

#### 2.2 任务优先级

按 must / should / nice 排序，**前 3 个任务必须是 must**（确保哪怕参与者中途退出也已覆盖核心场景）。任务总时长建议控制在 45 分钟内，超出加休息。

#### 2.3 主持人脚本（moderator_script）

**warmup** 暖场（5 min）：
- 自我介绍 + 说明目的："我们今天在测产品，不是测你 —— 你卡住或觉得难都是产品的问题"
- 签录屏 / 录音同意
- 鼓励真实反应："不用客气，觉得糟就说糟"

**think_aloud_briefing** Think-Aloud 协议简介（2 min）：
- 演示一次：主持人拿手机大声说"我现在想找天气，我会点这个图标，因为它像云……"
- 强调："边操作边说你在看什么、在想什么 —— 哪怕'我不知道下一步做什么'也是有用的"

**task_intro_template** 任务介绍模板：
```
我现在给你一个场景：[scenario context]
你看到 [starting_point]，接下来你会怎么做？
（不要问我'要点哪里'，假装我不在你旁边，按你自己的想法来）
```

**neutral_probes** 中立追问：
- "你现在在想什么？"
- "你期望接下来发生什么？"
- "你看到什么让你这么做？"
- "如果这个按钮不在这里你会去哪找？"
- "刚才那一下犹豫了一下，能说说吗？"

**debrief** 收尾（5-10 min）：
- "整体过程哪里最难？哪里最顺？"
- "如果你能改一处，会改什么？"
- "和你平时用的 [对比产品] 比有什么不同？"

#### 2.4 反偏见提示（bias_warnings）

主持人必须警惕的 6 条偏见：

1. **救场偏见**：用户卡住不要立刻提示 —— 等至少 30 秒沉默，再问"你现在在想什么"
2. **引导偏见**："你是不是觉得这个按钮难找？" → 改成："你刚才在屏幕上看什么？"
3. **解释设计**：用户问"这个是干嘛的" → 不解释，反问"你觉得是干嘛的？"
4. **附和偏见**：用户骂设计 → 不附和"对呀这做得不好"，保持中立"嗯"
5. **任务介入**：用户走偏路径 → 不纠正"应该在那里" → 让用户继续，看会发生什么
6. **总结偏见**：debrief 时不替用户总结"所以你觉得 X 不好"→ 让用户自己说

#### 2.5 观察团协作协议（observation_team）

> Noah Weiss 原则：**"Make testing a team sport."** PM / 工程师 / 设计同事同步观看，能极大提升团队共识，避免事后"我觉得用户不会这么用"的争论。

每场测试组建观察团 2-4 人，遵守以下协议：

1. **静音观察席**：远程会议设置"仅主持人可发声"；现场用单向玻璃 / 隔壁会议室转播
2. **共享笔记 doc / Slack 频道**：观察者实时记录"惊讶 / 疑惑 / 想追问"，但不打断主持人
3. **每场 debrief 15 分钟**：本场结束后立即开短会，每人说"最惊讶的 1 件事 + 1 个想追的问题"，主持人决定下一场要不要调整探针
4. **不打分、只观察**：观察者不在现场下结论"这个用户笨"或"这个设计没问题"，留到 Step 4 Analyze 团队共同定性
5. **debrief_cadence 三档**：
   - `after-each-session`：高频迭代 / RITE / 高风险场景必用
   - `end-of-day`：常规 8 场测试
   - `end-of-study`：异步 Unmoderated 测试

**反偏见**：观察者越早进入越好（避免设计者只听到主持人转述的二手信息，产生认知偏差）。

### Step 3 — Conduct 现场观察记录

每场测试现场或事后填写一份记录，对应 `sessions[].task_results[]`。

#### 3.1 现场记录模板

```yaml
participant_id: "P3"
segment: "新用户"
date: "2026-05-26"
duration_min: 42
recording_url: "..."
task_results:
  - task_id: "T1"
    success: partial            # success / partial / fail / skipped
    time_to_complete_sec: 187
    errors: 2                   # 走错路径的次数
    assists_requested: 1        # 主动求助次数
    verbatim_quotes:
      - "这个图标看起来不能点……"
      - "我猜应该是这个吧？"
    stuck_points:
      - "onboarding 第 2 步：看不到下一步按钮（10:32）"
      - "权限弹窗：直接拒绝（10:34）"
    timestamp: "00:08:15"
```

#### 3.2 成功度分级标准

- **success**：无主持人帮助，1 次走通路径，达到全部成功标准
- **partial**：走通但绕路 / 用了主持人提示 / 只完成部分成功标准
- **fail**：放弃 / 主持人主动叫停 / 走错完全无法回头
- **skipped**：技术故障 / 用户拒绝

#### 3.3 RITE 节奏特别说明

如果用 RITE，**每 1-2 个参与者后**立即开短会决定：
- 看到的问题是不是真问题（≥ 2 人遇到）
- 能不能马上改（改完不影响后续测试的同质性）
- 改完继续下一批

RITE 不追求统计量，追求"以最快速度收敛设计缺陷"。

#### 3.4 Unmoderated 异步特别说明

Maze / UserTesting 等工具自动产出 task_success_rate / heatmap / 视频录像，但**缺失"为什么"维度**。建议：
- 异步收 20-50 人量化基线
- 选 3-5 个有典型问题的参与者，跟进做 Moderated 深挖

### Step 4 — Analyze 严重度评级与修复优先级

#### 4.1 任务级量化（task_metrics）

按 task_id 聚合：

```yaml
- task_id: "T1"
  success_rate: 0.50              # 8 人中 4 人 success
  avg_time_sec: 220               # 远超 estimated_time_min × 60
  avg_errors: 1.6
  assist_rate: 0.375              # 8 人中 3 人求助
```

**红线指标**：success_rate < 70% 或 assist_rate > 30% 的任务，必出 critical / catastrophic finding。

#### 4.2 Findings 提炼

每个反复出现的 stuck_point 转成 1 条 finding：

```yaml
- id: "F1"
  task_id: "T1"
  description: "onboarding 第 2 步'下一步'按钮被识别为装饰元素，用户找不到"
  severity: 3-critical
  frequency: 6                    # 8 人中 6 人卡
  affected_participants: [P1, P3, P4, P5, P7, P8]
  evidence_quotes:
    - "[P3] 我点了半天都不知道下一步在哪"
    - "[P5] 那个按钮我以为是装饰，没想到能点"
  suggested_fix_direction: "提升按钮视觉权重（Primary 色 + 增大）；考虑添加'继续→'文字提示"
  recommended_next_skill: flow-mobile
```

#### 4.3 Nielsen 严重度 0-4 级

| 等级 | 名称 | 定义 | 处置 |
| --- | --- | --- | --- |
| 4 | catastrophic 灾难性 | 用户无法完成核心任务 / 数据丢失 / 系统崩溃 | **上线前必须修** |
| 3 | critical 严重 | 用户能完成但需大量帮助 / 严重挫败感 | **上线前必须修** |
| 2 | major 主要 | 反复出现，影响效率，用户能自己绕过 | **首版修复优先级 P1** |
| 1 | minor 轻微 | 偶发，不影响完成 | P2/P3，可批量修 |
| 0 | cosmetic 外观 | 视觉细节，无功能影响 | 视情况修，不阻塞上线 |

**严重度判定不仅看频次**：1 人遇到的 catastrophic（如数据丢失）也必须修；6 人遇到的 cosmetic 仍是 cosmetic。

#### 4.4 频次 × 严重度矩阵

```
                        频次 high (≥50%)        频次 low (<50%)
severity 3-4    ┃    🔴 P0 立即修              🟠 P1 上线前修
severity 2      ┃    🟠 P1 上线前修            🟡 P2 首版后修
severity 0-1    ┃    🟡 P2 批量修              ⚪ P3 视情况修
```

#### 4.5 修复优先级与设计回流（vertical slice 分组）

> 借鉴 brief-to-tasks 的 vertical slice 思维：每条 finding 不只是"待修问题"，而是"可独立交付的修复 slice"，附带"复用/改/新建" + "依赖前置 finding"。

每个 P0/P1 finding 输出 `redesign_recommendations`：

```yaml
- finding_id: "F1"
  priority: P0
  owner_skill: flow-mobile
  rationale: "8 人中 6 人卡住核心任务 → 直接影响产品激活率"
  slice_layer: core-ui          # foundation / core-ui / interactions-states / polish
  component_action: modify      # reuse / modify / create
  affected_components: ["OnboardingStep2", "Button/Primary"]
  depends_on: []                # 无前置；若依赖 F3 修完才有意义则填 ["F3"]
```

**slice_layer 四档**（修复顺序：foundation → core-ui → interactions-states → polish）：

| 层 | 含义 | 示例 finding |
| --- | --- | --- |
| **foundation** | 底层规范 / token / 全局导航 / 模板 | "全站 Primary 按钮色与文本对比度均不足" |
| **core-ui** | 页面级核心组件 / 主路径屏幕 | "Onboarding 第 2 步按钮识别不到" |
| **interactions-states** | 状态、反馈、异常 | "提交失败后无错误提示" |
| **polish** | 视觉细节、动效、文案润色 | "成功 toast 停留时间过短" |

**component_action 三档**（喂给 PRD 估工）：

- **reuse**：现有 SparkDesign 组件已经能解决，只是没用对（最便宜）
- **modify**：现有组件需要扩展属性 / 行为
- **create**：要新做组件 / 页面（最贵，建议先 reuse/modify 兜底再说）

**depends_on 排序**：foundation 类不要标 depends_on（自己就是地基）；core-ui 若依赖 foundation 修复则标依赖 ID；避免循环依赖。

**Pilot 修复建议**：P0 finding 数量 ≥ 5 时，**先挑 1-2 个最有把握的修复试制**，找 2-3 个新参与者快跑 RITE 验证，确认方向再批量改，避免一次性大改后再发现新问题。

#### 4.6 Markdown 报告输出

保存到 `spark-output/test/[project-slug].md`：

```markdown
# Test — [项目名]

- **生成时间**：[ISO8601]
- **测试类型**：[moderated-remote / unmoderated / ...]
- **原型保真度**：[hi-fi / production]
- **参与者**：[N] 人（segment 1: [n] / segment 2: [n]）
- **任务数**：[M] 个（must [a] / should [b] / nice [c]）
- **测试时间**：[date range]

## 任务量化结果

| 任务 | 成功率 | 均时（秒） | 平均错误 | 求助率 |
| --- | --- | --- | --- | --- |
| T1 完成首次配置 | 🔴 50% | 220 | 1.6 | 37.5% |
| T2 ... | 🟢 87.5% | 95 | 0.2 | 0% |

## Findings（按 severity × frequency 排序）

### 🔴 [F1] onboarding 第 2 步'下一步'按钮识别不到
- **任务**：T1
- **严重度**：3-critical
- **频次**：6/8（75%）
- **代表性原话**：
  > [P3] "我点了半天都不知道下一步在哪"
  > [P5] "那个按钮我以为是装饰"
- **建议修复方向**：提升按钮视觉权重；添加文字提示
- **回流 Skill**：`/mobile页面设计`（重做 onboarding 第 2 屏组件）

### 🟠 [F2] ...

## 严重度分布

- 🔴 catastrophic: [c]
- 🟠 critical: [cr]
- 🟡 major: [mj]
- ⚪ minor: [mn]
- ⚪ cosmetic: [co]

## 修复优先级（vertical slice 分组）

按 slice_layer 修复顺序排：

### Foundation（地基，先修）
- [ ] **[F?]** [描述] · P[?] · _modify · 涉及：[组件]_

### Core UI（核心组件 / 主路径屏）
- [ ] **[F1]** Onboarding 第 2 步按钮重做 · **P0** · _modify · 涉及：OnboardingStep2, Button/Primary · 依赖：—_
- [ ] **[F?]** ... · P[?] · _create_

### Interactions & States
- [ ] **[F?]** [描述] · P[?] · _reuse · 复用 Edge/EmptyState_

### Polish
- [ ] **[F?]** [描述] · P[?] · _modify_

**Pilot 建议**：P0 共 [n] 条，先挑 [F1] / [F4] 试制 → RITE 3-5 人快速验证 → 确认方向再批量改。

## 下一步建议

- **回流 `/异常态`**：F4 的"权限拒绝后无引导"需要补 Edge 设计
- **回流 `/Web页面设计`**：F1 重做 onboarding 第 2 屏
- **进入 `/设计度量`**：把 T1 成功率 50% 作为上线基线，目标改版后 ≥ 80%
- **进入 `/设计提案`**：用本报告作为重设计的证据
- **进入 `/设计复盘`**：catastrophic finding 反推哪步设计决策跑偏
```

#### 4.7 双通道 Context 输出

按 [chain-protocol.md](../../chain-protocol.md) §2.1 v1.1 智能适配规则：

**Step 1 — 写盘到 `spark-output/context/test.json`**（必做）：

```json
{
  "skill": "test",
  "generated_at": "<ISO8601>",
  "project_name": "...",
  "test_plan": {
    "goal": "...",
    "research_questions": ["..."],
    "test_type": "moderated-remote",
    "prototype_fidelity": "hi-fi",
    "prototype_url": "...",
    "sample_size": 8,
    "recruitment_criteria": ["..."],
    "environment": "zoom",
    "session_length_min": 45,
    "timeline": "..."
  },
  "task_scenarios": [
    {
      "id": "T1",
      "title": "...",
      "context": "...",
      "starting_point": "...",
      "success_criteria": ["..."],
      "observation_focus": ["..."],
      "estimated_time_min": 5,
      "priority": "must"
    }
  ],
  "moderator_script": {
    "warmup": ["..."],
    "think_aloud_briefing": ["..."],
    "task_intro_template": "...",
    "neutral_probes": ["..."],
    "debrief": ["..."],
    "bias_warnings": ["..."]
  },
  "sessions": [
    {
      "participant_id": "P1",
      "segment": "...",
      "date": "...",
      "duration_min": 0,
      "recording_url": "...",
      "task_results": [
        {
          "task_id": "T1",
          "success": "success|partial|fail|skipped",
          "time_to_complete_sec": 0,
          "errors": 0,
          "assists_requested": 0,
          "verbatim_quotes": ["..."],
          "stuck_points": ["..."],
          "timestamp": "..."
        }
      ]
    }
  ],
  "findings": [
    {
      "id": "F1",
      "task_id": "T1",
      "description": "...",
      "severity": "0-cosmetic|1-minor|2-major|3-critical|4-catastrophic",
      "frequency": 0,
      "affected_participants": ["P1"],
      "evidence_quotes": ["..."],
      "suggested_fix_direction": "...",
      "recommended_next_skill": "flow-web|flow-mobile|edge|brief|sitemap|stories"
    }
  ],
  "task_metrics": [
    {
      "task_id": "T1",
      "success_rate": 0.0,
      "avg_time_sec": 0,
      "avg_errors": 0,
      "assist_rate": 0.0
    }
  ],
  "severity_summary": {
    "catastrophic": 0,
    "critical": 0,
    "major": 0,
    "minor": 0,
    "cosmetic": 0
  },
  "redesign_recommendations": [
    {
      "finding_id": "F1",
      "priority": "P0|P1|P2|P3",
      "owner_skill": "flow-mobile",
      "rationale": "..."
    }
  ]
}
```

> ⚠️ **severity_summary 字段自动 derive 规则（强制）**：`catastrophic/critical/major/minor/cosmetic` = 对 `findings` 按 `severity` 分组计数。**禁止手写估算**——必须从 findings 数组 programmatic 计算得出。若发现 severity_summary 与 findings 不一致，以 findings 数组为准重新计算。

**Step 2 — chat 输出紧凑 marker**：

```
<!-- spark-context:test ref="spark-output/context/test.json" -->
Test 已保存：project=[name]，[N] 人 × [M] 任务 → [K] 条 finding（catastrophic [c] / critical [cr] / major [mj]）；任务成功率均值 [X]%；P0 [p0] 条 / P1 [p1] 条
<!-- /spark-context:test -->
```

**降级 fallback**：若写盘失败，输出完整 JSON marker 作为唯一持久化通道。

### Handoff 提示（必输出）

> **协议**：按 [`_shared/next-skill.md`](../../_shared/next-skill.md) 三层结构模板输出；前 5 候选由 `_shared/skill-graph.json` 的依赖图算法实时算（done ⊆ ready，按 next_hint.preferred → alternatives → 同阶段 → anchor → fan-out 排序），优先建议从 `_shared/skill-graph.json#skills[id="test"].next_hint` 读取。

**首行模板**：`✅ 可用性测试 已完成，任务量化基线 + Nielsen 0-4 严重度已沉淀。`

**本 Skill 的 `next_hint`**（来自 skill-graph.json，**不可在此 SKILL.md 内硬编码覆盖**）：

- **preferred**：`/metric`
- **优先理由**：可用性测试结果直接转可观测指标，进 Metric 把『测试发现的瓶颈』变成『上线后可追踪』。
- **alternatives**：`/retro` (项目结束直接做复盘)
- **emoji**：🧪

**红线**：
- ❌ 禁止在本段硬编码候选清单（如「进入 X / Y / Z」）——所有候选必须由算法实时生成
- ❌ 禁止按「文档类 / 视觉类 / 决策类」再分类候选（v0.5.5 起，分类已折叠进 next_hint.alternatives）
- ❌ 禁止与「更新链路面板」段合并——两段必须各自独立成段，中间空一行
- ❌ 禁止漏第 2 行候选清单——即使候选只有 1 个、或为空（终端节点）也要写出来

---

## 质量标准

1. **每条 finding 有完整证据链**：必须含 task_id + severity + frequency + affected_participants + verbatim_quotes + suggested_fix_direction，不能只写"用户觉得不好用"
2. **任务剧本场景化非指令化**：不写"点击注册按钮"，写"假设你想开始用 X"
3. **成功标准可观察**：success_criteria 是"用户做了什么动作"，不是"用户满意"
4. **严重度按 Nielsen 0-4 级**：不自创等级，便于跨项目对照
5. **量化与质化并存**：task_metrics 提供 success_rate 等量化基线，findings 提供原话 + 上下文
6. **修复优先级有依据**：priority 必须有 rationale，不能只是 P0 / P1
7. **任务前 3 个必须是 must**：保证哪怕参与者退出也覆盖核心
8. **样本量 < 5 标"早期信号"**：5 人以下不能下"X% 用户卡住"结论，称"早期可用性信号"
9. **试测（pilot）必须做**：正式测试前必跑 1 场 pilot 调整剧本
10. **反偏见提示必须出现在 moderator_script 里**：bias_warnings 字段不能省略
11. **cosmetic 不等于不值得修**（Judd Antin / Airbnb 7 字案例：改 7 个字符赚百万）：cosmetic finding 若涉及 CTA / 转化路径 / 信任感关键词，必须单独标注商业杠杆，不能简单丢进 P3
12. **多方案对比时不孤立打分**：Kristen Berman 原则 —— 同一参与者内做相对评估，看哪个版本完成率更高、卡点更少，而不是只给每个方案打孤立的"5 分制"评分
13. **观察团必到场**：PM / 工程 / 设计同事至少 1 人同步观看，避免事后转述失真

## 红线规则

1. **不编造 quote**：所有 verbatim_quotes 必须来自真实录屏 / 笔记，禁止 AI 生成
2. **不在测试中辩护设计**：用户骂某个设计时主持人不解释"这是因为……"，保持中立
3. **Think-Aloud 不能引导**："你觉得这里难吗"是引导问题；"你现在在想什么"是中立
4. **不让用户预测自己的行为**：不问"你会用这个功能吗"（自我预测不准），问"刚才你怎么做的"
5. **不在 task_intro 里暴露界面词汇**：不说"找到 settings"，说"你想调整通知"
6. **不下"全部用户"结论**：8 人样本不能说"用户都觉得"，说"8 人中 6 人卡住"
7. **不替代真实可用性测试**：本 Skill 提供方案 + 整理方法，不能替代亲眼观察用户操作
8. **不替代专业 UX 研究团队**：跨文化 / 敏感人群 / 高风险场景测试建议找专业用研

---

## 输入不足处理

- **用户没有原型**：明确告知 Test 需要可操作物，建议先做完 Flow Web/Mobile 或最简 hi-fi 再回来
- **用户没有上游 brief / stories**：先问 3 个最小问题（"测什么、测哪些任务、用户是谁"），再启动 Plan
- **用户只想"快速测一下"**：推荐 RITE（3-5 人即时迭代）或 5-Second（第一印象），不必跑全套 8 人
- **样本量过少（< 3 人）**：明确标"早期信号"，不出量化结论
- **没有录屏权限**：可用纸笔记录 + 时间戳；告知"verbatim 准确度会下降"
- **跨语言测试**：分语言归纳 finding，跨语言聚类时标"语言文化差异"
- **测试已经跑完但记录稀疏**：能做的只到 finding 级别，无法回填 task_metrics 量化数据

---

## 实操注意事项

### 与 Probe 的协作节奏

**典型链路**：Probe（设计前挖根因）→ Brief → 设计执行 → **Test（设计后验证）** → 改 → 再 Test。Probe 和 Test 共享部分语料（如情感原话），但 Test 必须基于真实任务行为，不能复用 Probe 的访谈。

### 与 Check 的协作节奏

**理想顺序**：先 Check（自查走查清单，发现明显问题）→ 改完 → 再 Test（用真实用户验证剩下的隐性问题）。Check 不能替代 Test —— heuristic 走查发现 ~30-50% 问题，Test 才能发现"用户实际怎么用"。

### 与 Metric 的协作节奏

**Test 输出的 `task_success_rate` 是 Metric 的金标基线** —— 上线后用同样的任务定义跑漏斗，看真实流量下是否达到 / 偏离 Test 的预期。

### 时间投入建议

| 测试类型 | 时间投入 |
| --- | --- |
| 仅做 Plan + Script | 4-8 小时 |
| Pilot 试测 + 调整 | 半天 |
| Moderated 正式 8 场 | 4-5 天（含每天 2-3 场） |
| Unmoderated 异步 30 人 | 3-7 天（自动化） |
| RITE 1 轮 5 场 | 1 天 |
| Analyze 整理 | 1-2 天 |

### 样本量建议

| 测试目的 | 推荐样本 | 说明 |
| --- | --- | --- |
| Moderated 探索性 | 5-8 人 / segment | Nielsen 经典：5 人能发现 ~85% 可用性问题 |
| Moderated 比较性 A/B | 5-8 人 × 2 组 | 每组同样剧本 |
| RITE 迭代 | 3-5 人 × N 轮 | 不追求统计量 |
| Unmoderated 基线 | 20-50+ | 量化基线 |
| 5-Second / First-Click | 20-30 | 视觉 / IA 决策 |

### 工具选择速查

- **Moderated 远程录屏**：Zoom（录屏 + 共享）/ Lookback（专为用研设计）/ 飞书会议
- **Unmoderated 异步**：Maze（原型 + 数据）/ UserTesting（含真实用户池）/ Useberry
- **5-Second / First-Click**：Maze / UsabilityHub
- **卡片分类 / Tree Test**（IA）：Optimal Workshop
- **国内常用**：腾讯文档协作记录 / 钉钉录屏 / 飞书妙记自动转录

---

## 已知限制

- **AI 不能替你做主持**：本 Skill 提供脚本和方法，主持需要真人对真人
- **AI 不能替你看录屏**：finding 提炼依赖人工 / 团队回看视频和笔记
- **小样本结论有偏差**：5-8 人不代表全体用户，关键决策需 Unmoderated 大样本或上线后 Metric 验证
- **不替代真实可用性测试观察**：纯文本记录会丢失"用户在哪屏停了 3 秒"这类行为信号
- **Unmoderated 缺失"为什么"维度**：自动化工具给指标但不给原因，建议混合使用
- **严重度评级带主观性**：Nielsen 0-4 级仍有判断空间，建议团队 2 人独立打分后讨论
- **不替代专业用研团队**：跨文化 / 高风险 / 敏感人群 / 大规模定量需专业资源

