mcpField
T
testing

testing

github.com/bsene测试与质量7163 次安装1 周前更新
代码仓库

关于 testing

testing 是面向开发者和编码 Agent 的软件测试策略技能,帮助选择测试层级、提升可测试性,并为 Agent 编写的代码制定测试方法。

主要功能

  1. 01选择合适的测试层级
  2. 02优先验证可观察行为
  3. 03优先使用真实协作者而非模拟对象
  4. 04指导编码 Agent 测试
  5. 05涵盖生产环境反馈实践

适用场景

  1. 01规划新功能的测试
  2. 02从难写的测试发现设计问题
  3. 03为 Agent 编写的代码设置防护
  4. 04减少脆弱或过大的 E2E 测试集

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/bsene/skills --skill testing

安装后在 Claude Code 中输入/testing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
acceptance-testing.md
ai-agent-testing.md
async-and-time.md
bdd-review.md
martin-fowler-testing.md
mocks-and-fragility.md
principles.md
smoke-tests.md
tcrdd.md
tdd-and-atdd.md
test-strategy.md
testdesiderata.md
trustworthy-tests.md
unit-testing-principles.md
web-api-testing.md
xp-testing-practices.md
references/smoke-tests/
curl.md
hurl.md
references/tcrdd/
autonomous-execution.md
benchmarks.md
example-and-errors.md
further-reading.md
git-cycle.md
phase-guide.md
pragmatics.md

详细介绍

测试——策略与理念

测试不是事后验证,而是对设计的反馈。难以编写的测试揭示了生产代码中的耦合。难以命名的测试揭示了对行为的理解不够清晰。测试套件是系统的动态规范——明确代码实际上应该做什么。无论代码由人类还是 AI Agent 编写,这一点都成立。


核心理念

理念实践含义可避免的反模式
难以测试 = 设计有问题重构设计,而不是测试为了强行实现可测试性而模拟一切
测试是规范,而非验证将测试命名为描述行为的句子根据实现细节命名测试
模拟是异味,而非策略优先使用真实协作者或伪对象充斥模拟对象、即使存在 Bug 也能通过的测试套件
纯函数是理想的可测试性方案将 I/O 推到边界;让业务逻辑保持纯粹业务逻辑与副作用纠缠在一起
通过必须意味着可以发布构建失败是停止发布的信号,而非噪声反复重试不稳定的测试,直到测试套件碰巧通过
测试行为,而非设计原则SRP 和其他架构规则指导代码应如何组织;应断言代码做了什么,而不是它是否遵循某项设计规则统计方法数量、检查类的职责,或断言是否符合 SOLID,而不是验证可观察到的结果

测试组合

测试金字塔描述的是一种实用的默认分布,而非硬性规定。单元测试构成底层,因为它们快速且精确。更高层级的测试也很有价值,因为它们会检验连接、协作和用户旅程。测试组合原则是:选择能为场景提供所需信心的最低成本层级。

层级数量速度目的脆弱性
单元测试多ms纯行为规范聚焦行为时较低
组件测试一些ms–秒通过公共接口测试一个可部署的服务低至中
集成测试一些秒在一个进程/系统中使用真实协作者中
契约测试一些ms–秒服务边界处的消费者/提供者预期聚焦契约时较低
E2E/UI少量秒–分钟首次出现的用户旅程高——应尽量减少
生产环境持续近实时合成监控和领域可观测性运维层面——不能替代其他测试

如果高层级测试发现了 Bug,应先在最低的有效层级复现,再进行修复。聚焦的回归测试是永久的防护措施;高层级测试则是发现问题的机制。


决策指南

问题答案 → 行动
这是纯行为问题还是连接问题?纯行为 → 单元测试;连接 → 组件/集成测试
场景是否跨越服务边界?是 → 针对消费者/提供者预期编写契约测试;E2E 保留给一个用户旅程
这是关键用户旅程吗?编写一个 E2E 测试,然后将各种变化推到更低层级
我需要模拟对象,还是可以使用真实协作者?优先使用真实协作者;仅当对外交互本身就是待测行为时才使用模拟对象
测试很难编写吗?将此视为设计反馈;在添加更多替身之前先重构
测试是否依赖计时或非确定性 I/O?修正设计;快速测试必须具有确定性
我是否见过这个测试在应该失败时失败?否 → 注入一个明显的 Bug,确认测试失败,然后撤销更改
生产环境中的行为会让我们意外吗?添加合成监控、领域可观测性,或进行探索性调查
谁在主导——人类还是 AI Agent?人类 → TCRDD 微步骤;Agent → 采用独立信任信号的测试优先批次

使用 AI 编码 Agent 进行测试

严格遵循红/绿/重构流程,是为了管理_人类_的短期记忆。Agent 的情况正好相反——工作记忆容量大,但容易产生幻觉,也容易钻测试的空子,而不是满足测试要求。因此,测试节奏和信任模型都需要调整。

旧有假设Agent 时代的调整
强制采用微步骤 TDD,以获得快速反馈让 Agent 先编写测试,再分较大的批次实现
作者可以测试自己的代码分离测试编写者和编码者的角色,避免测试将缺陷本身固化
代码审查是主要的兜底手段结合覆盖率、变异测试、复杂度指标和有针对性的人工审查
验收测试是普通的代码产物将其视为编码 Agent 必须遵守的不可变护栏
差异越小越好优先考虑连贯的测试分组,而不是为了缩小差异而分散测试
生产环境检查是可选的持续监控提示词/输出质量、偏移、延迟和故障模式

有关完整的流水线和信任模型,请参阅 使用 AI 编码 Agent 进行测试。对于大模型应用,还请阅读 Martin Fowler 的测试纲要。


测试反模式

反模式问题修正
过度使用模拟模拟会掩盖集成错误优先使用真实协作者或伪对象
测试实现细节重构时测试会失效测试可观察行为,而不是方法调用图
脆弱/不稳定的测试结果会变成噪声隔离状态;控制时间、随机性和异步完成情况
缓慢的单元测试设计耦合过于紧密重构设计,而不是测试
过于庞大的 E2E 测试套件收益递减;每种变化都要付出全部成本保留一条 E2E 路径,并将变化下沉到较低层级
仅通过 E2E 测试服务边界成本高且脆弱添加消费者驱动的契约测试
在测试中编写逻辑测试可能带有它本应捕获的同一个错误使用硬编码的预期值,不使用控制流
将覆盖率视为质量高覆盖率仍可能意味着断言薄弱用覆盖率查找缺口;用变异测试/契约测试检验测试强度
没有生产环境反馈循环未知的故障模式仍不可见添加可观测性、合成监控和探索性测试
跳过遗留代码测试重构期间风险会不断增加在改变行为前建立特征化测试网
AI Agent 测试自己的代码测试会将错误写入规范分离测试编写者和编码者的角色
Agent 为了通过而弱化验收测试防护措施被破坏让编码 Agent 无法修改验收测试
将架构规则作为行为进行测试结构规则不是用户可见的行为用静态分析强制执行架构;测试可观察结果

综合示例

之前——难以测试(问题出在设计上):

function sendOverdueReminders() {
  const users = db.query("SELECT * FROM users WHERE balance < 0");
  for (const user of users) {
    if (Date.now() - user.lastReminded > WEEK) {
      emailClient.send(user.email, "You owe us money");
    }
  }
}

这个函数迫使测试控制数据库、时钟和电子邮件客户端。业务规则——应该提醒谁——被埋在副作用中。

诊断: 将 I/O 推到边界,并保持规则纯粹。

之后——纯核心,I/O 位于边界:

function usersToRemind(users, now) {
  return users.filter(
    (user) => user.balance < 0 && now - user.lastReminded > WEEK,
  );
}

function sendOverdueReminders() {
  for (const user of usersToRemind(db.allUsers(), Date.now())) {
    emailClient.send(user.email, "You owe us money");
  }
}

usersToRemind([...], fixedNow) 是一个无需替身的一行单元测试。其余外壳只是一个轻量级集成问题。通过改变设计,而不是添加模拟,就能让难以测试变得易于测试。


按需阅读

阅读场景文件
了解四项跨领域测试原则测试原则
根据 12 项理想属性审查测试质量TestDesiderata — 质量审计
审查测试是否符合 BDD 及其结构BDD 测试审查
指导 AI 编码 Agent:节奏、流水线、信任模型使用 AI 编码 Agent 进行测试
选择模拟什么以及断言什么模拟对象与脆弱性
审查测试的可信度、可维护性和可读性可信且可维护的测试
将场景分配到不同测试层;测试配方;遗留代码评估测试策略与遗留代码
测试异步代码、计时器、事件或伪造模块异步、时间与模块伪造
应用 Fowler 风格的测试组合、测试替身、生产环境反馈和 LLM 实践Martin Fowler 的测试准则
为 CI 门禁识别并编写冒烟测试(Hurl 或 curl)冒烟测试
绿灯时自动提交、失败时自动还原的红/绿/重构(TCR/TCRDD)TCRDD
根据 Given/When/Then 场景驱动行为;crap + mutation 质量门禁验收测试工作流
测试风格、函数式核心、模拟边界、数据库测试、反模式(Khorikov)单元测试原则
测试优先节奏:伪造、三角验证、可测试设计、验收 TDD(Koskela)TDD 与 ATDD
测试 Web API:基于风险的检查、契约、性能、安全、SLOWeb API 测试
Arrange-Act-Assert、模拟对象、来自 c2 wiki 的 TDD 笔记XP 测试实践

基准测试

场景:.benchmarks/scenarios/testing-001-agent-test-strategy.md · 运行:2026-08-31 · 日志:.benchmarks/runs/2026-08-31/testing-001-agent-test-strategy.json

模型未使用使用变化
claude-opus-4-867%100%+33%
claude-sonnet-4-6100%100%+0%
claude-haiku-4-567%100%+33%

通过(运行于 2026-08-31)。Opus 和 haiku 提升 +33;sonnet 已达上限。门禁依据 .agents/skills/skill-optimizer/rules/release-gates.md。

评论

支持 Markdown