ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

把 testing.md 从 CLAUDE.md 常驻噪音里拆出来:Claude Code 按 paths 加载测试规约的配置实践

把 testing.md 从 CLAUDE.md 常驻噪音里拆出来:Claude Code 按 paths 加载测试规约的配置实践 1. 为什么 testing.md 不该常驻在 CLAUDE.md 里如果你正在用 Claude Code 维护一个中大型前端仓库大概率遇到过这种情况CLAUDE.md 越写越长从技术栈、目录结构、提交规范一路写到测试命名、mock 边界、快照策略。刚开始觉得省事所有约定都在一个文件里Claude Code 一进仓库就全知道。但用久了会发现模型在改一个package.json或者写一个README.md的时候脑子里还背着「测试用例必须清理副作用」这条规则注意力被稀释了。问题不在于规则本身写错了而在于规则出现的时机不对。写业务组件时Claude Code 不需要知道 React Testing Library 的断言风格改构建脚本时它也不需要记住测试名要用should ... when ...结构。这些测试规约只有在它真正读到*.test.ts或*.test.tsx文件时才有价值。常驻在 CLAUDE.md 里等于每一轮推理都带着一份用不上的说明书。Claude Code 的.claude/rules/目录提供了一种模块化项目指令机制允许把大型项目里的约定拆成多个主题文件。更关键的是规则文件可以通过 frontmatter 里的paths字段绑定到特定路径只有当 Claude Code 正在处理匹配文件时才加载进上下文。这意味着 testing.md 可以从常驻噪音变成一张「路径触发的小纸条」——平时不占上下文遇到测试文件才出现。这套机制对多包仓库尤其明显。一个仓库里可能同时有 Angular、React、Node.js 的代码e2e、单元测试、集成测试混在不同 package 中。测试约定如果常驻每一轮推理都要带着它走按路径加载后它只在真的遇到测试文件时进入工作记忆。上下文越干净模型越容易把注意力放在当前任务上。下面我会给出可复制的拆分配置、paths 匹配写法以及改动前后上下文占用与触发效果的验证步骤。2. 前置准备TaoToken 接入 Claude Code 的配置在动手拆分 testing.md 之前先确认你的 Claude Code 已经能正常跑起来。如果你是通过 TaoToken 接入的需要准备好三件套Base URL、API Key、Model ID。这三样缺一不可很多人卡在 401 或者local proxy failed上基本都是这里没对齐。TaoToken 的 API 地址是https://taotoken.net/api注意这个地址不带任何查询参数。API Key 在控制台的 API Keys 页面生成生成后复制保存页面上不会再次完整显示。Model ID 则取决于你要用的模型比如 Claude 系列或其它兼容模型具体以文档里的模型列表为准。配置 Claude Code 时环境变量是最直接的方式。你可以在 shell 的配置文件里写入也可以用项目级的.env。下面这组是通用的写法export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_API_KEYsk-你的key export ANTHROPIC_MODELclaude-sonnet-4-20250514如果你用的是 Claude Code 的 settings 文件也可以写进~/.claude/settings.json或者项目级的.claude/settings.json。项目级配置适合团队共享个人配置适合本地调试。注意不要把真实 Key 提交到仓库.claude/settings.local.json通常会被 gitignore 覆盖。配置完成后先用一个最小请求验证连通性。可以直接在终端里跑curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $ANTHROPIC_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 64, messages: [{role: user, content: ping}] }如果返回里能看到content字段和一段文本说明 Base URL 和 Key 都没问题。如果返回 401检查 Key 是否复制完整、是否有多余空格如果返回local proxy failed检查 Base URL 是否写成了带路径的形式正确写法就是https://taotoken.net/api不要在后面加/v1之外的额外路径。这一步看起来和 testing.md 拆分没关系但它是后面所有验证的前提。Claude Code 连不上paths 规则加载得再对也看不到效果。如果你还没有 Key可以去控制台的 API Keys 页面生成一个文档页有完整的接入说明。3. 可复制配置CLAUDE.md 与 testing.md 的拆分写法现在进入正题。拆分的核心思路是CLAUDE.md 只放全局共识testing.md 放测试场景知识两者通过.claude/rules/目录和paths字段协作。先看目录结构。推荐这样组织项目根/ ├── .claude/ │ ├── CLAUDE.md │ ├── settings.json │ └── rules/ │ ├── testing.md │ ├── api.md │ └── ui.md ├── src/ │ ├── components/ │ └── api/ └── package.json.claude/rules/下的 Markdown 文件会被递归发现也可以组织到frontend/、backend/这样的子目录中。没有paths的规则会像项目级.claude/CLAUDE.md一样在启动时加载带有paths的规则只会在匹配路径出现时生效。先写 CLAUDE.md。它应该只保留「一进仓库就该知道」的内容比如技术栈、常用命令、目录结构、业务名词。测试相关的具体约束全部移出去。# 项目全局约定 ## 技术栈 - TypeScript React 18 - 构建Vite - 测试Vitest Testing Library - 包管理pnpm ## 常用命令 - 安装依赖pnpm install - 启动开发pnpm dev - 运行测试pnpm test - 类型检查pnpm typecheck ## 目录结构 - src/componentsUI 组件 - src/api接口封装 - src/utils纯函数工具 ## 业务名词 - Cart购物车 - Checkout结算流程注意这里没有任何测试命名、mock 策略、副作用清理的内容。这些全部交给 testing.md。接下来是 testing.md。它放在.claude/rules/testing.md顶部用 YAML frontmatter 声明paths。文件名只是给团队看的真正决定加载时机的是paths字段。--- paths: - **/*.test.ts - **/*.test.tsx - **/*.spec.ts - **/*.spec.tsx --- # 测试规约 ## 测试命名 - 使用 should [expected] when [condition] 结构 - 测试名要能独立表达场景、条件和预期 - 避免 renders correctly、should work 这类含糊命名 ## Mock 边界 - 只 mock 外部依赖HTTP 请求、数据库、支付网关、浏览器存储、第三方 SDK - 不轻易 mock 仓库内部模块内部逻辑默认真实执行 - 优先断言用户可见行为而不是内部实现细节 ## 副作用清理 - 每个测试结束后恢复 mock、timer、DOM 和全局状态 - 使用 afterEach 统一清理不要依赖测试执行顺序 - 异步测试等待可观察结果不要用固定 sleep ## 快照 - 快照只用于稳定结构不用于掩盖复杂断言 - 避免无意义的大快照这里有几个细节值得展开。**/*.test.ts中的**表示任意层级目录所以src/components/Cart.test.tsx和packages/web/src/api/user.test.ts都能命中。如果你只写*.test.ts它可能只匹配项目根目录下的测试文件深层目录会漏掉。官方文档里的路径模式也展示了类似思路**/*.ts匹配任意目录下的 TypeScript 文件src/**/*匹配src/下所有文件src/components/*.tsx限制到特定目录。如果你还想给 API 层和 UI 层分别加规则可以再建两个文件。api.md绑定到src/api/**/*.tsui.md绑定到src/components/**/*.tsx。这样每条规则都不大却都能在该出现时出现。--- paths: - src/api/**/*.ts --- # API 层约定 - 所有请求走统一的 request 封装 - 错误统一转换为领域错误 - 不在组件里直接调用 fetchsettings.json 里可以配置权限和 hooks但 testing.md 本身不需要在 settings 里注册。.claude/rules/下的文件会被自动发现。如果你用的是 Claude Code 的 coding-plan 模式规则加载逻辑是一样的区别只在于任务编排方式。4. 验证请求与成功结果确认 paths 真的生效配置写完后最关键的一步是验证 paths 是否真的按预期触发。很多人配完就以为生效了结果发现 testing.md 根本没被加载或者加载了但没起作用。下面给出一套可复现的验证流程。第一步确认规则文件被识别。在 Claude Code 里执行一个简单任务比如让它读一下当前项目的规则。你可以直接问它「当前项目有哪些规则文件」如果 testing.md 被识别它应该能说出这个文件的存在。如果它完全不知道检查文件是否放在.claude/rules/下以及 frontmatter 的---是否写对。第二步验证路径触发。打开一个测试文件比如src/components/Cart.test.tsx然后让 Claude Code 补一个测试用例。观察它的输出如果 testing.md 生效它生成的测试名应该符合should ... when ...结构并且会主动加afterEach清理。如果它生成的是renders correctly这种名字说明规则没加载。第三步验证非测试文件不触发。打开一个普通业务文件比如src/components/Cart.tsx让 Claude Code 改一个样式。如果 testing.md 没有常驻它不应该在回答里提到测试命名或 mock 策略。如果它莫名其妙开始讲测试规约说明规则被错误地常驻加载了检查paths是否写成了空或者通配符过宽。第四步对比上下文占用。Claude Code 的上下文窗口是有限的规则常驻会占用一部分。你可以通过一个简单实验感受差异把 testing.md 的内容临时复制进 CLAUDE.md然后让 Claude Code 处理一个非测试文件观察它的回答是否变得更「平均」、更犹豫。再把它移回.claude/rules/testing.md重复同样的任务。实测下来拆分后模型在非测试任务上的回答更聚焦因为它不用再背着测试规约。如果你用的是支持 token 统计的界面可以直接看每轮请求的输入 token 数。拆分前CLAUDE.md 里塞了测试规约每轮输入都会多出几百 token拆分后只有处理测试文件时才会多出这部分。对于长会话这个差异会累积得很明显。第五步验证规则冲突。在 CLAUDE.md 里故意写一句「可以 mock 内部模块」然后在 testing.md 里写「不轻易 mock 内部模块」。打开一个测试文件让 Claude Code 写测试观察它听谁的。正常情况下路径规则更具体应该优先。如果它开始犹豫或者两边都提说明规则冲突需要清理。比较好的做法是把全局规则写得原则化把路径规则写得更具体测试相关的具体约束集中放在 testing.md。验证通过后你就有了一个按路径加载的测试规约。它不会在写 README 时打扰你也不会在改构建脚本时分散注意力只在真正处理测试文件时出现。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth配置和验证过程中最容易卡住的不是 paths 写法而是接入层的报错。下面按真实报错逐条排查。401 Unauthorized。这是最常见的。原因通常是 API Key 没配、配错、或者带了多余字符。检查ANTHROPIC_API_KEY是否完整复制前后有没有空格或换行。如果你用的是 TaoToken 的 Key确认它是在控制台的 API Keys 页面生成的并且没有过期。另外检查 Base URL 是否写成了https://taotoken.net/api如果写成了带/v1的完整路径有些客户端会拼接出错误地址导致鉴权失败。local proxy failed。这个报错通常出现在客户端尝试走本地代理但代理没起来的时候。检查你的环境变量里有没有残留的代理配置比如HTTP_PROXY、HTTPS_PROXY。如果有先清掉再试。另外确认 Base URL 没有写成http://localhost之类的本地地址。正确写法就是https://taotoken.net/api不要加额外路径。reading choices 相关报错。这类报错通常出现在响应格式不符合预期时比如客户端期望 OpenAI 格式的choices字段但实际返回的是 Anthropic 格式的content。检查你用的客户端是否支持 Anthropic 协议。Claude Code 本身走的是 Anthropic 协议如果你用其它工具接入需要确认它支持对应的消息格式。Model ID 也要写对写错模型名有时会返回空响应进而触发解析错误。OAuth 相关报错。如果你在 Claude Code 里看到 OAuth 登录提示说明它没有走 API Key 模式。检查是否设置了ANTHROPIC_API_KEY有些版本会优先走 OAuth。如果你用的是 Codex 的auth.json配置方式确认文件路径和字段名正确。Base URL、Key、Model ID 三件套要写全缺一个都可能回退到 OAuth 流程。规则不生效。如果接入没问题但 testing.md 就是不触发检查三件事文件是否在.claude/rules/下frontmatter 的paths是否用了正确的 YAML 格式路径模式是否匹配到了实际文件。可以用**/*.test.ts这种宽匹配先验证再逐步收窄。规则加载了但模型不遵守。testing.md 是软指导不是硬约束。它能影响模型生成测试的倾向但不能保证每次都百分百遵守。要做硬约束应该放到 hooks、eslint 或 CI 里。比如测试文件必须通过 eslint这不该只写在 testing.md应该在package.json、eslint.config或 CI 里 enforce。软指导和硬约束组合起来开发体验才顺。排查时建议按「接入层 → 规则文件 → 路径匹配 → 模型行为」的顺序逐层验证不要一上来就怀疑模型。大部分问题都出在前三层。6. 把测试知识从常驻上下文里拿出来testing.md 的价值不是多写了一个 Markdown 文件而是把测试知识从常驻上下文里拿出来变成按路径触发的局部规则。它让 Claude Code 在处理*.test.ts和*.test.tsx时更像一个懂团队测试习惯的工程师在处理其他文件时又不会背着测试规范到处跑。如果你还在把所有规范塞进 CLAUDE.md可以从 testing.md 开始拆。先建.claude/rules/testing.md把测试命名、mock 边界、副作用清理这三件事移进去加上paths声明。然后在 CLAUDE.md 里删掉对应内容只留全局共识。跑一遍验证流程确认测试文件触发、非测试文件不触发。真正值得长期保留的配置往往不是那些写得最长的配置而是加载时机最准确的配置。testing.md 小到只有几行却能把测试场景的关键约束稳定注入。对一个持续演进的 TypeScript 仓库来说这种小规则比一份臃肿的总规范更耐用。如果你还没有配置好接入可以先从 API Keys 页面生成一个 Key再对照接入文档把 Base URL 和 Model ID 写对。需要长期跑编码任务或 Agent 流程的话Coding Plan 会更合适。配置过程中遇到报错优先按第 5 节的顺序排查大部分问题都能定位到接入层或路径匹配上。
返回列表