2026年10月1日 · 阅读 —
陌生系统的测试从哪开始?先建 8 问最小模型,再谈用例
unfamiliar-system-testing
还不懂系统?先建最小测试模型、生成测试方向、显式管理未知——再开始测
上手引导 · 暴露未知 · 生成测试点 · 估算风险
目录
是什么
unfamiliar-system-testing 是一个模型无关的通用 skill——自包含的技能包(SKILL.md + prompts + references + evals + 校验脚本),Codex、Claude 及其他任意模型宿主均可加载使用。它引导测试人员在还不理解系统的情况下开始测试。它不抛出通用清单,而是先建立最小测试模型(8 问),把信息分成事实 / 假设 / 未知,按维度生成该考虑的测试点与方向,并提供跨业务类型兜底层和测试理论方法——让测试人员知道该考虑什么、往哪测、下一步找谁确认。
它是「上手引导 + 测试点启发」的陪伴工具,不是执行引擎,也不是技能路由器。当测试人员明确了要做哪类测试(API 契约、性能、安全、UI 自动化)时,discover-testing 会路由到更专的 testing-types/* 技能;本 skill 提供的是进入那些技能之前的「理解 + 方向生成」层。
为什么需要
在陌生系统上开始测试,通常要么对着空白发懵,要么贴来一大堆无关紧要的通用用例。两者源于同一个根因——对一个还没验证的系统做推理:
| 直觉(反模式) | 本 skill 的做法 |
|---|---|
| “先把整个架构学完再测” | 先建_最小_模型,边测边学 |
| 照搬通用测试点清单 | 结合当前系统裁剪,不适用就标 不适用 |
| 把口头解释 / 旧文档当事实 | 标为”假设”,设计证据去验证 |
| 信息不足仍假装确定 | 显式列出未知,写明找谁确认 |
| “我觉得错了”却没有依据 | 先定义预言机(凭什么判断对错) |
| 把判断权外包给 AI | AI 只当挑战者/复核者,不当结论来源 |
与直接问大模型的区别
两者都能”生成测试点”,区别在于是什么在塑造输出——是这个 skill 固定的、扎根于_你当前系统_的契约,还是裸聊窗口里模型临时发挥的结果。
| 维度 | 直接问大模型(Raw LLM) | 本 skill |
|---|---|---|
| 输出由什么驱动 | 模型的训练数据 + 当前对话记忆临时拼出来 | 固定的 8 问最小测试模型,扎根于你当前系统 |
| 事实 vs 假设 | 倾向于把猜测包装成自信的结论 | 强制做事实 / 假设 / 未知三分;未知写明由谁确认、用什么验证 |
| 测试广度 | 通用清单,换个问法就漂移 | 10 个维度 × A–H 兜底裁剪到当前系统,不适用显式标 不适用 |
| 怎么判断”错了” | 模型说”看起来有问题” | 先定义预言机——这个系统凭什么判断对错 |
| AI 的位置 | 结论来源 | 挑战者:先攻击你的第一版计划,由你逐条判断 |
| 可重复性 | 依赖提示词,每次问都不一样 | 输出契约确定,每次结构一致 |
用本 skill 而不是裸问的场景:
- 系统陌生、一旦”自信地错”代价很高。
- 你需要的是能站得住脚的测试方向,而不只是一堆用例。
- 你希望输出可审计:哪条是事实、哪条是假设、每个缺口找谁确认。
- 你必须把通用清单收窄到这一个系统,并显式标出哪些不适用。
裸问就够了的时候: 你已经理解系统、问题窄且偏事实性、即使答错也没多大代价。
核心概念
- 最小测试模型:只回答当前任务需要的 8 问(目的、用户、输入输出、业务规则、状态、依赖、失败行为、最大损失点)。不必第一天就懂所有模块。
- 未知管理:“我还没懂”是工作状态,不是结论。每个缺口记录三件事:缺哪块信息、谁最可能知道、可用什么观察/实验验证。显式写出未知,比用一个未经验证的答案填上去更安全。
- 事实 vs 假设 vs 未知:口头说明和旧文档在转成可观察、可复现的证据之前都是假设。
- 预言机优先:每个测试方向都要有判断结果对错的标准。没有预言机的断言就是”我觉得它错了”,不可信。
- happy path + failure path:不仅测正确操作路径,还要覆盖输入 / 权限 / 依赖 / 网络 / 状态这些失败路径。
- 风险优先级:用影响 × 可能性的风险矩阵量化”最大损失处”(第 8 问),决定先测谁。
目录结构
unfamiliar-system-testing/
├── SKILL.md # 激活入口(frontmatter + 规则)
├── prompts/unfamiliar-system-testing.md # 完整执行规范(8 问模型、输出结构)
├── agents/openai.yaml # 发现元数据 + 隐式调用策略
├── references/
│ ├── test-point-dimensions.md # 10 类测试点维度,结合当前系统裁剪
│ ├── business-type-use-cases.md # 跨业务类型兜底(电商/支付/CRM/搜索/IAM/Agent/...)
│ ├── testing-theory-techniques.md# 等价类/边界值/决策表/状态迁移/探索式/基于风险/...
│ ├── ai-usage.md # AI 当复核者/挑战者,不当结论来源
│ └── heuristics-oracles.md # 测试预言机、SFDPOT、FEW HICCUPPS、风险矩阵、charter 模板
├── evals/
│ ├── eval.yaml # 评测 harness(schema v1alpha1,claude_code 引擎)
│ └── cases/ # basic-success / edge-incomplete-input / edge-narrow-unknown
└── scripts/validate_skill_package.py # 契约校验 + 密钥/绝对路径扫描
| 路径 | 职责 |
|---|---|
SKILL.md | 激活入口:何时使用、定位、核心约束、执行流程、按需加载、交付前自检、常见误区。 |
prompts/unfamiliar-system-testing.md | 完整执行规范:8 问最小模型、未知管理、方向生成 Step 1–6、预言机优先、输出结构、最低覆盖清单。 |
references/test-point-dimensions.md | 10 个维度分类(功能、输入校验、状态、权限、依赖、网络、性能、兼容性、安全、发布),含”裁剪或标注不适用”指引。 |
references/business-type-use-cases.md | 分业务类型兜底测试点(A–H),⭐ = 最容易翻车的高风险点,命中才懒加载。 |
references/testing-theory-techniques.md | 12 种经典技术,附”陌生系统首轮先选谁”的对照表。 |
references/ai-usage.md | 如何在有基线的前提下把 AI 当挑战者/复核者;AI 不知道什么。 |
references/heuristics-oracles.md | 预测言机问题、SFDPOT / FEW HICCUPPS 启发式、2×2 风险矩阵、探索式 charter 模板、API 黑盒契约检查。 |
agents/openai.yaml | 发现元数据(display name、描述、隐式调用策略)。 |
evals/ | 规则化评测:一个成功用例 + 两个边界用例(输入不完整、窄目标未知)。 |
evals/cases/*.yaml | 每个用例的 prompt、must_not_contain、规则化 judge。 |
scripts/validate_skill_package.py | 校验包契约(必备文件、标题、懒加载引用、用例接线),并扫描凭据特征与绝对本机路径。 |
快速开始
环境要求: Python 3(仅标准库,无第三方依赖)。
校验包契约
python3 scripts/validate_skill_package.py unfamiliar-system-testing
# → PASS: unfamiliar-system-testing package contract
运行评测用例(用 skill-up 针对你的引擎跑)
skill-up run unfamiliar-system-testing # 或:skill-up run evals/eval.yaml
评测 harness 含三个规则化用例—— basic-success、edge-incomplete-input、edge-narrow-unknown ——锁定”最小模型 + 未知管理”的预期行为。
实例
下面是一场真实的工作流对话:测试人员 + 运行本 skill 的模型。测试人员几乎什么都不知道——没有架构文档、还没看代码,只有一行需求。注意 skill 是如何先建最小模型、区分事实 / 假设 / 未知、把测试方向裁剪到当前系统、并始终给出下一步该找谁确认——而不是甩出一张通用清单。
背景。
orders-export是一个遗留 Python 服务:把订单行导出成 CSV 落到共享 SFTP。需求变更:“给导出加一个user_id过滤参数”。
测试人员: 我要测”导出加按 user_id 过滤”。我几乎没有任何背景。从哪开始?
Skill(运行本 skill 的模型): 先别碰任何用例——先建这个变更涉及的_最小模型_。我只问这 8 个问题里当前需要的,答不上来的标成 Unknown,而不是猜。
- 目的 —— 现在导出时按
user_id过滤行。✅ 事实(来自需求) - 用户 —— 谁调用它?API 消费方(内部),以及扫描 SFTP 目录的配置。⚠️ 假设 —— 需确认
- 输入输出 —— 入参:新增可选
user_id;输出:只含该用户订单行的 CSV。user_id存在但导出中没有该行 → 该行应被排除?Unknown - 规则 ——
user_id与现有过滤(如日期区间)互斥还是叠加?组合时必填还是可选?Unknown - 状态 —— 空结果集、超大结果集、无订单的用户、已删除的 user_id。暂无测试定义。
- 依赖 —— 订单的 DB 读取路径、CSV 写、SFTP 上传。过滤发生在去重之前还是之后?
Unknown - 失败行为 —— 非法/缺失
user_id、大过滤下 DB 超时、SFTP 宕机。尚不知。 - 最大损失点 —— 若导出了不属于该用户的订单(过滤绕过),这是数据泄露型失败:最高风险。
测试人员: “过滤绕过”听着吓人。那我_到底_先测什么?
Skill(运行本 skill 的模型): 先定义 oracle。写用例之前,先定”怎么判断结果是错的”。对本次变更,oracle 是 “user_id=7 的 CSV 里只含 orders.user_id = 7 的行” —— 可与 DB 快照对比验证。现在把测试点裁剪到这个系统(不是通用清单):
- Happy path ——
user_id=7→ CSV,所有行匹配,表头未破坏。 - 边界 / 输入 ——
user_id传非数字字符串、传0、传一个存在但无订单的值(空 CSV 但正常退出)。 - 过滤绕过(failure path) —— 当某个订单行属于其他用户时,它是否还残留在导出里?用混合批次导出并对输出做 diff。这是 ⭐ 最高风险点。
- 状态 —— 过滤与现有日期区间过滤叠加;两个过滤同时用(2 行?排除边界?)。
- 依赖 —— 大
user_id(1 万+ 订单)→ DB 查询超时行为;SFTP 上传仍落地。 - 兼容 / 回归 —— 不带
user_id调用端点必须仍返回旧的完整导出(不静默改变)。
测试人员: 有几个我确实不知道答案。
Skill(运行本 skill 的模型): 好——这是”还没懂”的工作状态,不是阻塞。下面是显式未知清单,每条都给出谁可确认和如何验证:
| 未知项 | 问谁 | 如何验证 |
|---|---|---|
user_id 与日期过滤互斥还是叠加? | API 负责人(@backend-oncall) | 读合并后的 PR / 直接问,别猜 |
| 过滤发生在去重前还是后? | 数据团队(@data-warehouse) | 读合并 diff 里的查询计划 |
DB 里不存在的 user_id 会怎样? | 服务负责人 | 在 staging 用假 id 复现 |
最高风险优先:过滤绕过的用例——静默数据泄露的代价远大于漏一个空批次边界。
测试人员: 我该让模型直接把这些用例写出来吗?
Skill(运行本 skill 的模型): 把 AI 定位成挑战者,不是作者。你自己先写第一版测试计划;再让模型攻击它——指出漏洞(状态组合、过滤、你漏掉的 oracle)。每条建议由你判断。本 skill 禁止在未经验证的情况下采用生成出来的业务规则。
这场对话正是本 skill 的完整闭环:最小模型 → 裁剪后的测试方向 → 带负责人的显式未知 → oracle-first → 下一步。测试人员最终拿到的是简短、可验证、有优先级的计划,而不是一面无关通用用例的墙。
提示:要对着评测 harness 重放这个场景(三个规则化用例),装好 skill-up 后运行
skill-up run unfamiliar-system-testing。
功能与用法
- 8 问最小模型:目的、用户、输入输出、规则、状态、依赖、失败行为、最大损失——只建当前任务所需;缺失项标
Unknown。 - 事实 / 假设 / 未知三分:口头说明和旧文档变成带验证手段的假设;信息缺口显式标注,给出负责人与验证实验。
- failure path 覆盖:从一条 happy path 扩展出输入 / 权限 / 依赖 / 网络 / 状态各方向的测试点。
- 跨业务类型兜底:电商、支付/账务、CRM、搜索、IAM、AI/LLM/Agent、数据集成、消息——命中才懒加载,⭐ 高风险点优先。
- 测试理论工具箱:等价类、边界值、决策表、状态迁移、探索式(charter)、基于风险、成对、蜕变性、谓词/不变式。
- 预言机优先纪律:每个方向先定义”用什么判断对错”;用影响 × 可能性矩阵给风险打分。
- AI 当挑战者而非来源:让 AI 挑战你的测试计划而不是替你产出结论。
- 可校验:契约校验脚本 + 三个规则化评测用例。
- 零敏感信息:校验脚本扫描凭据特征与绝对本机路径;示例从不携带真实密钥。
安全边界与设计原则
- 绝不虚构业务规则。不理解系统时,禁止把未经验证的规则写成结论——未知要显式写出来,而不是掩盖。
- 先模型后点。不给测试点时强行圆一个模型,或只有模型没有方向,都算不合格。
- 清单是围栏,不是剧本。维度清单和业务类型兜底是”结合当前系统裁剪”的触发点,绝不整段照搬。
- AI 是挑战者。AI 生成的内容未经人工判断,一律不当业务规则或结论使用。
- 不虚构内容。输出结构、优先级、预言机、下一步都来自当前系统和测试人员的证据,不沿用外部约定。
评测与自检
-
包契约 + 密钥/绝对路径扫描:
python3 scripts/validate_skill_package.py unfamiliar-system-testing # 期望输出:PASS -
评测 harness(规则化,三个用例):
skill-up run unfamiliar-system-testing
FAQ(常见问题)
这是测试执行框架吗? 不是。它产出最小模型、测试方向、未知清单和下一步。当需要特定测试类型时,discover-testing 路由到专门的 testing-types/* 技能。
用户几乎不给信息怎么办? “未知管理”纪律接管:输出带缺口的最小模型,写明每个缺口找谁确认、用什么实验验证——绝不为显得自信而编造业务规则。
覆盖所有业务类型吗? 兜底层覆盖 A–H(电商、支付、CRM、搜索、IAM、AI/Agent、数据集成、消息)。类型命中才懒加载;⭐ 高风险点是入手的最安全位置。
为什么每个方向都要预言机? 在陌生系统上,“看起来不对”而没有标准是不可靠的。先定义预言机(一致性、文档、领域模型、历史等),测试方向才有意义。
能让 AI 直接生成测试计划吗? 在你还没有基线时,本 skill 明确反对。它把 AI 定位为挑战者/复核者:你先写第一版计划,AI 挑战,你逐条判断。
实例: 陌生系统的测试从哪开始?先建 8 问最小模型,再谈用例
接到一个没看过的系统,测试通常从两个地方开始。
要么对着空白发懵,半天写不出一条用例。
要么贴来一大堆通用清单,看着面面俱到,其实跟这个系统半毛钱关系没有。
这两种我都试过。它们不是方法问题,是同一个根因:对一个还没验证的系统做推理。你还没搞懂它,就开始猜它会怎么错。
后来我把我惯用的那套做法做成了一个开源 skill,放在 GitHub 上:xsoway/unfamiliar-system-testing。模型无关,Codex、Claude 或其他宿主都能加载。这篇就讲清楚它到底解决了什么,为什么这么设。
先搞清楚:你到底在测什么
在陌生系统上,最容易掉进去的坑是把别人的解释当事实。
口头的说明、过期的文档,在被转成可观察、可复现的证据之前,都只是假设。AI 会说”看起来这里有问题”,这不是判断,是语气。
所以我的第一个决定很简单:先建一个最小测试模型,把信息砍成三类——事实、假设、未知。
什么是”事实”?来自需求、能直接拿来用的。什么是”假设”?听来的、还没验证的。什么是”未知”?我还没懂的部分——而”还没懂”是工作状态,不是结论。
这三类不能混在一起。混了,未知就会被某个看着很自信的答案填上,而这个答案可能根本没验证过。
8 问,只问当前任务需要的
最小模型不是把整个系统都学完再测。它只回答当前任务需要的 8 个问题:
- 目的:这次改动要达成什么
- 用户:谁在调用、谁在消费
- 输入输出:入参出参是什么
- 业务规则:规则之间互斥还是叠加
- 状态:空集、超集、无权限等等边界
- 依赖:数据读取、写入、外发这些路径
- 失败行为:非法输入、超时、下游宕机
- 最大损失点:哪里错了代价最高
回答不了的就标 Unknown,而不是猜。这 8 问不是第一天就要答全,先答当前任务需要的。
规矩我定死了:先有模型再有测试点。不给测试点、硬圆一个模型不算;只有模型、给不出测试方向也不算。前者是糊弄,后者是空谈。
风险不是凭感觉,是按影响 × 可能性打分
最大损失点就是第 8 问。它决定你先测谁。
拿一份影响 × 可能性的矩阵,给每个潜在失败点打分。最高的那个点,通常不是功能最复杂的地方,而是”错了就兜不住”的地方——数据泄露、钱算错、权限被绕过。
这类点在业务上是跨类型的,所以我在 skill 里做了 A–H 的兜底层:电商、支付/账务、CRM、搜索、IAM、AI/LLM/Agent、数据集成、消息。每个类型标了 ⭐ 高风险点,命中才懒加载——不命中就不加载,免得把清单又搬成剧本。
清单是围栏,不是剧本。它是触发你的点,不是让你整段照抄的答案。
一个例子:给导出加 user_id 过滤
这是 skill 里带的一个完整工作流对话,我用它说明整个流程怎么走。一个遗留 Python 服务 orders-export,把订单行导出成 CSV 落到 SFTP。需求变更:加一个按 user_id 过滤的参数。
测试人员几乎什么都不知道,一行需求,没架构文档,没看过代码。
Skill 没有甩用例。它先问这几个问题里当前需要的部分:
- 目的:导出时按
user_id过滤行,这是事实,来自需求。 - 用户:API 消费方、扫 SFTP 的配置。这是假设,得确认。
- 输入输出:新增可选
user_id,输出只含该用户订单行。那user_id存在但没订单,该行要不要出现?未知。 - 规则:
user_id和现有日期过滤互斥还是叠加?未知。
注意这里的关键一步:先定义 oracle,再写用例。
对本例,oracle 是——“user_id=7 导出的 CSV,只含 orders.user_id = 7 的行”,可以直接跟 DB 快照对比验证。没有 oracle,断言就是”我觉得它错了”,不可信。
然后测试点才开始出现,而且裁剪到这个系统:
- happy path:
user_id=7导出,所有行匹配,表头没破坏。 - 输入边界:传非数字、传
0、传一个存在但没订单的值。 - failure path(⭐ 最高风险):某个订单行属于其他用户时,它会不会残留进导出里?用混合批次导出再 diff。这是过滤绕过,静默数据泄露,代价最高。
- 状态:与现有日期过滤叠加。
- 依赖:1 万+ 订单时 DB 超时行为,SFTP 是否仍落地。
- 回归:不带
user_id调用必须仍返回旧的完整导出,不能静默改变。
答不上来的地方,显式列成未知表,每条写清问谁、怎么验证:
| 未知项 | 问谁 | 如何验证 |
|---|---|---|
user_id 与日期过滤互斥还是叠加 | API 负责人 | 读合并后的 PR,别猜 |
| 过滤发生在去重前还是后 | 数据团队 | 读查询计划 |
DB 里不存在的 user_id | 服务负责人 | staging 用假 id 复现 |
最后测试人员拿到的是:最小模型 → 裁剪到当前系统的测试方向 → 带负责人的未知清单 → 定义了 oracle → 按风险排序的下一步。
AI 是挑战者,不是结论来源
有人问:这些用例让 AI 直接生成不就行了?
我的答案很直接:在你还没有基线之前,不行。
直接问大模型,输出由训练数据和临时记忆拼出来,它倾向于把猜测包装成自信的结论,通用清单换个问法就漂移,还容易把你的判断权外包出去。
所以 skill 把 AI 定位成挑战者:你自己先写第一版测试计划,再让 AI 攻击它——指出你漏掉的状态组合、你没想到的过滤、你还没定义的 oracle。每条建议由你判断要不要采纳。
本 skill 禁止在未经验证的情况下采用 AI 生成出来的业务规则。AI 不知道你的系统里发生过什么,它只是比你更快地提出”可能哪里会翻车”。
它不是一个执行框架
这个 skill 不替你跑测试。它是「上手引导 + 测试点启发」的陪伴层:产出最小模型、测试方向、未知清单和下一步。
当你想清楚要做哪类测试了——API 契约、性能、安全、UI 自动化——它会路由到更专的 testing-types/* 技能。它负责的是进入那些技能之前的”理解 + 方向生成”。
还没做完的事
路线图里,8 问模型、10 维清单、A–H 兜底、测试理论工具箱、预言机纪律、AI 当挑战者、契约校验、双语文档都标了完成。
剩下的是:更多业务类型兜底(金融科技、DevOps)和逐类型的评测用例。
如果你想一起补这部分,欢迎提 PR。提交前让包契约保持绿色,遵循它自己的证据规则——说明改了什么、怎么验证、有什么风险。文件里不能有真实密钥、个人数据或绝对路径。
**路线图
- 8 问最小测试模型 + 事实/假设/未知三分
- 10 维测试点清单,含”裁剪或标不适用”指引
- A–H 跨业务类型兜底层,⭐ 高风险点标记
- 测试理论工具箱与选择对照表
- 预言机优先纪律 + 影响×可能性风险矩阵
- AI 当挑战者的用法与提示词模板
- 包契约校验脚本 + 三个规则化评测用例
- 双语 README(中英文)+ gruvbox-material 主页
- 更多业务类型兜底(如金融科技、DevOps)与逐类型评测用例
项目地址
项目开源在 GitHub,MIT 协议:
github.com/xsoway/unfamiliar-system-testing
unfamiliar-system-testing —— 觉得有用的话,Star 一下;遇到问题到 GitHub Discussions 或 issue 提,公开渠道,不暴露个人邮箱。
判断一个陌生系统怎么测,最怕的是”自信地错”。这套东西要做的,就是让未知显式、让方向可验证、让每一步都有据可查——而不是让你在还不理解系统的时候,先写出一堆看起来对、其实无处安放的用例。
#测试工程 #测试开发 #AI-Skill #开源 #最小测试模型 #未知管理