test(generate-daily-poster): 补测降级路径 + 工作流固化「能力缺失测兜底」

A) 补测本环境可测但首版跳过的两环,回填报告与日志:
   - HTML 海报生成(layout-single 规格 + 真实数据):7 条布局断言全 PASS
     (标签平衡、5 主题行、0 值省略逐行+汇总、数据绑定)
   - 降级兜底(浏览器不可用时 HTML 落盘到用户目录):端到端跑通
   - 用例 6 拆为「HTML生成/降级兜底=可测已过」+「Playwright截图=环境不可测」
   - 结论仍为「有条件通过」,但边界从"整条渲染路径未测"收敛到"仅截图未测"

C) skill-dev-workflow.md ④ 验证新增「能力缺失时:测降级路径」小节:
   拆到可测/不可测最小粒度、缺失能力时必测其兜底、报告分行呈现并写补测条件;
   以本次 generate-daily-poster 迁移为反例

check-docs.py 通过。
This commit is contained in:
zhuguojie
2026-07-29 14:49:21 +08:00
parent 2ad626ceea
commit dffc47be41
3 changed files with 83 additions and 15 deletions
+8
View File
@@ -84,6 +84,14 @@
> 若用户此前有「不要测试发布 / 写入类功能」的约束,则写操作验证**默认不执行**:报告标注「未执行实测,原因:用户约束」,并降级为「有条件通过(写路径未实测)」。仅当用户对该操作给出一次性授权时才执行。
### 能力缺失时:测降级路径,别把整个功能标「未实测」
当运行环境缺某项能力(如无 Playwright MCP 无法截图、无某 CLI 子命令、外部服务不可达),**不要把整条功能路径笼统标成「未实测」**——那会把「环境真的测不了」和「其实可测但我跳过了」混成一句话,正是让用户验收时看不清边界的根源(本仓库迁移 `generate-daily-poster` 时就犯过:把 HTML 生成、降级兜底和 Playwright 截图一起标未实测,实际前两者本地可测)。正确做法:
1. **把路径拆到「可测 / 不可测」的最小粒度**:一个依赖缺失的功能,通常只有末端那一环真不可测,其前置与兜底往往是本地/只读操作、完全可测。
2. **缺失能力时,它的降级 / 兜底路径几乎总是可测的,且必须测**——因为当前环境正是该兜底的触发条件(没浏览器 → 正好验证「保留 HTML」兜底。兜底测不过比主路径缺失更危险。
3. **报告里分行呈现**,不合并:可测部分给真实用例与 ✅/❌;确实不可测的那环单列「未实测(原因:能力缺失 X并写明**补测条件**(需要什么环境)。结论用「有条件通过(仅 X 未实测)」,而非笼统的「未实测」。
### 日志协议(强制,防掩盖失败)
这次开发中 429 限流曾被 `&& echo ok` 掩盖成「静默成功」。为杜绝此类,日志**必须**
+13 -8
View File
@@ -13,7 +13,7 @@
## 测试用例
> 覆盖:只读数据链路(星球列表、主题 JSON + 字段校准)、打分公式核算、渲染前置(二维码、本地 HTTP 服务)Playwright 截图本身因环境无 MCP 未实测(用例6)。「实际」列摘录真实输出,完整原文见 [`logs/generate-daily-poster.log`](logs/generate-daily-poster.log) 对应用例段。
> 覆盖:只读数据链路(星球列表、主题 JSON + 字段校准)、打分公式核算、渲染前置(二维码、本地 HTTP 服务)、**HTML 海报生成 + 布局规则断言、降级兜底**。仅 Playwright 截图本身因环境无 MCP 未实测(用例8)。「实际」列摘录真实输出,完整原文见 [`logs/generate-daily-poster.log`](logs/generate-daily-poster.log) 对应用例段。
| # | 用例(意图) | 执行的命令 | 预期 | 实际(真实输出摘录) | 结论 |
|---|------------|-----------|------|---------------------|------|
@@ -22,7 +22,9 @@
| 3 | 打分公式核算(第 4 步) | `python3 verify_scoring.py`内嵌用例2 真实字段) | formula_score 按 scoring.md 公式算出、降序正确 | 「文件」=19.40 居首comments=1 的排在 comments=0 之上;同分稳定序 | ✅ |
| 4 | 二维码生成render-poster「二维码」 | `npx --yes qrcode "https://m.zsxq.com/groups/758421284/join.html" -o … -w 300` | 生成 300px PNG | `saved qrcode to: …``PNG image data, 300 x 300` | ✅ |
| 5 | 本地 HTTP 服务兜底render-poster「截图」步骤1 | `python3 -m http.server 8199 --directory .` + curl | 同源静态服务可访问 | `HTTP 200` | ✅ |
| 6 | Playwright 截图路径 | 预检 `browser_navigate` / `page.screenshot` / `browser_close` | 出 PNG | **本环境无 Playwright MCP 工具,未实测** | ⚠️ 未实测 |
| 6 | **HTML 海报生成 + 布局规则断言**render-poster「渲染 HTML」+ layout-single | `python3 gen_poster.py`layout-single 规格 + 用例2 真实数据) | 结构良好数据绑定0 值省略逐行+汇总生效 | 7 断言全 PASS标签平衡、5 主题行、likes 全 0 无 👍、主题#3 无 💬、绑定 💬7👀11、汇总 💬20👀56 | ✅ |
| 7 | **降级兜底**:浏览器不可用时保留 HTML 到用户目录render-poster「截图失败兜底」 | `cp … 日报-<ts>.html` 到模拟用户目录 + 校验可读 | HTML 按 `日报-<ts>.html` 落盘、可读、内容完整 | 落盘 2944 字节、首行 `<!doctype html>``.topic` 行数=5清理成功 | ✅ |
| 8 | Playwright 截图(正常路径最后一环) | 预检 `browser_navigate` / `page.screenshot` / `browser_close` | 出 PNG | **本环境无 Playwright MCP 工具,未实测** | ⚠️ 未实测 |
## 实测校准了哪些文档假设
@@ -39,13 +41,16 @@
## 未覆盖 / 已知风险
- **Playwright 截图路径用例6未实测**:本运行环境无 Playwright MCP`browser_*` 工具),故「浏览器预检 → 2x zoom → page.screenshot 出 PNG → browser_close」无法执行。该段文档系从原 `zsxq-report` skill 原样迁移、迁移中未改命令语义;渲染前置链路(数据/打分/二维码/HTTP 服务已由用例1-5 覆盖。**待在配有 Playwright MCP 的环境补测截图与降级兜底。**
- **多星球布局、二维码贴图后的实际视觉效果**未渲染验证(依赖同一截图能力)。
- 模型四维打分为主观评估,本次只核算了公式兜底分(客观、可复现的部分);模型分的质量不在静态验证范围
> 边界厘清:首版报告把「整条渲染路径」标为未实测,掩盖了其中可测的部分。本次补测后拆分如下——
- **HTML 生成用例6、降级兜底用例7已测通过**。二者是本地文件操作、不碰星球、不需 Playwright本环境完全可测
- **Playwright 截图本身用例8真不可测**。本环境无 Playwright MCP`browser_*` 工具),故「浏览器预检 → 2x zoom → page.screenshot 出 PNG → browser_close」无法执行。该段文档系从原 `zsxq-report` skill 原样迁移、未改命令语义。**待在配有 Playwright MCP 的环境补测截图与 PNG 视觉效果。**
- 多星球布局的实际视觉渲染同样依赖截图能力未做像素级验证结构规则已由用例6 的 layout-single 断言间接覆盖)。
- 模型四维打分为主观评估,本次只核算了公式兜底分(客观、可复现的部分);模型分质量不在静态验证范围。
## 结论
**有条件通过Playwright 截图路径未实测)。**
**有条件通过(Playwright 截图未实测;渲染前置 + HTML 生成 + 降级兜底均已实测通过)。**
- 只读数据链路(`group +list` / `group +topics --json`)、打分公式、渲染前置(二维码生成、本地 HTTP 服务兜底)均按预期工作,真实输出与文档一致;迁移中的字段回退、跨引用改写已按实测校准。
- 唯一未覆盖的是 Playwright 截图本身——因本环境缺 MCP 能力,非文档缺陷;该路径命令由旧 skill 原样迁移,风险低。补测条件明确(需 Playwright MCP 环境)。
- 只读数据链路(`group +list` / `group +topics --json`)、打分公式、二维码生成、本地 HTTP 服务、**HTML 海报生成(含 0 值省略等布局规则断言、降级兜底HTML 落盘到用户目录)** 均按预期工作,真实输出与文档一致;迁移中的字段回退、跨引用改写已按实测校准。
- 唯一未覆盖的是 Playwright 截图这一环——因本环境缺 MCP 能力,非文档缺陷;该路径命令由旧 skill 原样迁移,且其失败时的降级兜底已验证可用用例7风险低。补测条件明确(需 Playwright MCP 环境)。
@@ -151,19 +151,74 @@ render-poster「a. npx http-server … b. python3 -m http.server」回退链一
------------------------------------------------------------------------------
[用例6] Playwright 截图路径 —— 本环境未实测(能力缺失)
[用例6] HTML 海报生成 + 布局规则断言 —— render-poster「渲染 HTML」+ layout-single
------------------------------------------------------------------------------
(本地文件操作,不碰星球、不需 Playwright。按 layout-single.md 规格用用例2 的
真实 5 条主题生成 HTML并断言布局规则真的生效。脚本为可复现底稿。
$ python3 gen_poster.py ./zsxq-report-20260729.html
生成 ./zsxq-report-20260729.html2740 字节)
[PASS] HTML 标签闭合平衡
[PASS] 含 5 个 .topic 主题行
[PASS] likes 全为 0 → 无 👍0 值省略)
[PASS] 主题#3 comments=0 → 该行无 💬
[PASS] 主题#1 绑定 💬7 👀11
[PASS] 汇总 💬20 存在
[PASS] 汇总 👀56 存在
[exit 0]
校准layout-single.md 的 body 320px / 卡片 / footer-row 结构可从规格直接生成
结构良好的 HTML数据绑定正确「互动数据 0 值省略」规则逐行(主题#3 无 💬)
与汇总条likes 全 0 → 无 👍)均生效。
------------------------------------------------------------------------------
[用例7] 降级兜底 —— 浏览器不可用时保留 HTML 到用户目录render-poster「兜底」
------------------------------------------------------------------------------
(本环境正是"无 Playwright"这一兜底触发条件,故直接端到端验证兜底行为。)
$ mkdir -p ./mock-downloads
$ cp ./zsxq-report-20260729.html "./mock-downloads/日报-20260729140000.html"
[exit 0]
$ ls -l ./mock-downloads/
-rw-r--r--@ 1 pigrun staff 2944 7月 29 14:46 日报-20260729140000.html
[exit 0]
$ head -1 "./mock-downloads/日报-20260729140000.html"
<!doctype html>
[exit 0]
$ grep -c 'class="topic"' "./mock-downloads/日报-20260729140000.html"
5
[exit 0]
$ rm -rf ./mock-downloads ./zsxq-report-20260729.html # 清理
[exit 0]
$ ls zsxq-report-20260729.html
ls: zsxq-report-20260729.html: No such file or directory # 已清理
校准降级兜底可用——HTML 以 `日报-<timestamp>.html` 命名落到(模拟)用户
目录、可读、5 条主题完整。与 render-poster「截图失败兜底」1-3 步一致。
------------------------------------------------------------------------------
[用例8] Playwright 截图(正常路径的最后一环)—— 本环境未实测(能力缺失)
------------------------------------------------------------------------------
本运行环境无 Playwright MCP 工具(无 browser_navigate / browser_resize /
接受 async(page)=>{} 的截图工具),故 render-poster.md 的
接受 async(page)=>{} 的截图工具),故仅以下三段无法在本环境执行
- 浏览器可用性预检browser_navigate → about:blank
- 2x zoom + page.screenshot 出 PNG
- browser_close 清理
三段无法在本环境执行,未实测。
结论处理报告结论定为「有条件通过Playwright 截图路径未实测)」。该路径的
文档系从原 zsxq-report skill 迁移而来、迁移中未改其命令语义;渲染前置链路
HTML 拼装依赖的数据/打分/二维码/HTTP 服务已在用例1-5 覆盖。截图本身待有
Playwright MCP 的环境补测。
★ 边界厘清(本次补测的原因):
首版报告把"整条渲染路径"标为未实测,掩盖了其中可测的部分。实际拆分:
- HTML 生成用例6可测 → PASS
- 降级兜底用例7可测 → PASS
- Playwright 截图(本用例):真不可测(无 MCP→ 未实测
截图段文档系从原 zsxq-report skill 原样迁移、迁移中未改命令语义PNG 视觉
效果待有 Playwright MCP 的环境补测。
==============================================================================
日志结束