testing-patterns by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill testing-patterns一种务实的测试方法,强调:
这 不是传统的 TDD。而是:
在主对话中运行 50 个测试会消耗掉你的整个上下文窗口。通过委托给子代理:
| 命令 | 用途 |
|---|---|
/create-tests | 发现项目,生成测试规范 + 测试代理 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
/run-tests |
| 通过代理执行测试,报告结果 |
/coverage | 生成覆盖率报告并识别未覆盖的代码路径 |
快速工作流:
/create-tests → 生成 tests/specs/*.yaml + .claude/agents/test-runner.md
/run-tests → 生成代理,运行所有测试,保存结果
/run-tests api → 仅运行匹配 "api" 的规范
/run-tests --failed → 仅重新运行失败的测试
/coverage → 运行带覆盖率的测试,分析差距
/coverage --threshold 80 → 如果低于 80% 则失败
此技能提供 模式和格式。Claude 根据你的项目上下文设计实际的测试。
当你询问“为此项目创建测试”时会发生什么:
发现 - Claude 检查项目:
测试设计 - Claude 创建特定于项目的测试:
结构 - 使用此技能中的模式:
tests/ 目录中的 YAML 规范.claude/agents/ 中的可选测试代理tests/results/示例:
你:"为此 MCP 服务器创建测试"
Claude: [发现这是一个 Google Calendar MCP]
[看到工具:calendar_events, calendar_create, calendar_delete]
[设计测试用例:]
tests/calendar-events.yaml:
- list_upcoming_events (预期:数组,count_gte 0)
- search_by_keyword (预期:包含搜索词)
- invalid_date_range (预期:错误状态)
tests/calendar-mutations.yaml:
- create_event (预期:成功,返回 event_id)
- delete_nonexistent (预期:错误,包含 "not found")
此技能教会 Claude:
你的项目提供:
name: Feature Tests
description: What these tests validate
# Optional: defaults applied to all tests
defaults:
tool: my_tool_name
timeout: 5000
tests:
- name: test_case_name
description: Human-readable purpose
tool: tool_name # Override default if needed
params:
action: search
query: "test input"
expect:
contains: "expected substring"
not_contains: "should not appear"
status: success
| 规则 | 描述 | 示例 |
|---|---|---|
contains | 响应包含字符串 | contains: "from:john" |
not_contains | 响应不包含 | not_contains: "error" |
matches | 正则表达式模式匹配 | matches: "after:\\d{4}" |
json_path | 检查 JSON 路径处的值 | json_path: "$.results[0].name" |
equals | 精确值匹配 | equals: "success" |
status | 检查成功/错误 | status: success |
count_gte | 数组长度 >= N | count_gte: 1 |
count_eq | 数组长度 == N | count_eq: 5 |
type | 值类型检查 | type: array |
完整文档请参阅 references/validation-rules.md。
测试代理从会话继承 MCP 工具。创建一个代理,使其:
关键:如果你需要 MCP 访问权限,请 不要 指定 tools 字段。当你指定 任何 工具时,它就会变成一个允许列表,并且 "*" 会被按字面意思解释(而不是通配符)。完全省略 tools 以从父会话继承 所有 工具。
---
name: my-tester
description: |
测试 [domain] 功能。读取 YAML 测试规范并验证响应。
使用时机:变更后测试,运行回归测试。
# 省略 tools 字段 - 从父会话继承所有工具(包括 MCP)
model: sonnet
---
# [Domain] 测试器
## 工作原理
1. 查找测试规范:`tests/*.yaml`
2. 解析并执行每个测试
3. 验证响应
4. 报告通过/失败摘要
## 测试规范位置
tests/
├── feature-a.yaml
├── feature-b.yaml
└── results/
└── YYYY-MM-DD-HHMMSS.md
## 执行
对于每个测试:
1. 使用参数调用工具
2. 捕获响应
3. 应用验证规则
4. 记录 PASS/FAIL
## 报告
将结果保存到 `tests/results/YYYY-MM-DD-HHMMSS.md`
完整模板请参阅 templates/test-agent.md。
测试结果以 Markdown 格式保存,以便 git 历史记录:
# 测试结果:feature-name
**日期**:2026-02-02 14:30
**提交**:abc1234
**摘要**:8/9 通过 (89%)
## 结果
- test_basic_search - 通过 (0.3s)
- test_with_filter - 通过 (0.4s)
- test_edge_case - 失败
## 失败测试详情
### test_edge_case
- **预期**:包含 "expected value"
- **实际**:响应为空
- **参数**:`{ action: search, query: "" }`
保存到:tests/results/YYYY-MM-DD-HHMMSS.md
# tests/search.yaml
name: Search Tests
defaults:
tool: my_search_tool
tests:
- name: basic_search
params: { query: "hello" }
expect: { status: success, count_gte: 0 }
- name: filtered_search
params: { query: "hello", filter: "recent" }
expect: { contains: "results" }
复制 templates/test-agent.md 并根据你的领域进行自定义。
"运行搜索测试"
"在我的更改后测试 API"
"为 gmail-mcp 运行回归测试"
结果保存到 tests/results/。将它们提交以记录历史:
git add tests/results/
git commit -m "测试结果:8/9 通过"
同时运行多个测试代理以加速大型测试套件:
"并行运行这些测试套件:
- 代理 1:tests/auth/*.yaml
- 代理 2:tests/search/*.yaml
- 代理 3:tests/api/*.yaml"
每个代理:
为什么使用并行代理?
批处理策略:
对于 MCP 服务器,测试代理继承已配置的 MCP:
# 首先配置 MCP
claude mcp add --transport http gmail https://gmail.mcp.example.com/mcp
# 然后测试
"为 gmail MCP 运行测试"
MCP 测试规范示例:
name: Gmail Search Tests
defaults:
tool: gmail_messages
tests:
- name: search_from_person
params: { action: search, searchQuery: "from John" }
expect: { contains: "from:john" }
- name: search_with_date
params: { action: search, searchQuery: "emails from January 2026" }
expect: { matches: "after:2026" }
对于 REST API,使用 Bash 工具:
name: API Tests
defaults:
timeout: 5000
tests:
- name: health_check
command: curl -s https://api.example.com/health
expect: { contains: "ok" }
- name: get_user
command: curl -s https://api.example.com/users/1
expect:
json_path: "$.name"
type: string
对于浏览器自动化,使用 Playwright 工具:
name: UI Tests
tests:
- name: login_page_loads
steps:
- navigate: https://app.example.com/login
- snapshot: true
expect: { contains: "Sign In" }
- name: form_submission
steps:
- navigate: https://app.example.com/form
- type: { ref: "#email", text: "test@example.com" }
- click: { ref: "button[type=submit]" }
expect: { contains: "Success" }
search_with_date_filter 而不是 test1| 场景 | 使用此方法 | 使用传统测试 |
|---|---|---|
| MCP 服务器验证 | 是 | 否 |
| API 集成 | 是 | 辅以单元测试 |
| 浏览器工作流 | 是 | 辅以组件测试 |
| 单元测试 | 否 | 是 (Jest/Vitest) |
| 组件测试 | 否 | 是 (Testing Library) |
| 类型检查 | 否 | 是 (TypeScript) |
templates/test-spec.yaml - 通用测试规范模板templates/test-agent.md - 测试代理模板references/validation-rules.md - 完整的验证规则参考每周安装数
158
仓库
GitHub 星标数
650
首次出现
2026 年 2 月 2 日
安全审计
安装于
claude-code128
opencode108
gemini-cli100
replit97
codex94
cursor87
A pragmatic approach to testing that emphasises:
This is not traditional TDD. Instead:
Running 50 tests in the main conversation would consume your entire context window. By delegating to a sub-agent:
| Command | Purpose |
|---|---|
/create-tests | Discover project, generate test specs + testing agent |
/run-tests | Execute tests via agent(s), report results |
/coverage | Generate coverage report and identify uncovered code paths |
Quick workflow:
/create-tests → Generates tests/specs/*.yaml + .claude/agents/test-runner.md
/run-tests → Spawns agent, runs all tests, saves results
/run-tests api → Run only specs matching "api"
/run-tests --failed → Re-run only failed tests
/coverage → Run tests with coverage, analyse gaps
/coverage --threshold 80 → Fail if below 80%
This skill provides the pattern and format. Claude designs the actual tests based on your project context.
What happens when you ask "Create tests for this project":
Discovery - Claude examines the project:
Test Design - Claude creates project-specific tests:
Structure - Using patterns from this skill:
tests/ directory.claude/agents/tests/results/Example:
You: "Create tests for this MCP server"
Claude: [Discovers this is a Google Calendar MCP]
[Sees tools: calendar_events, calendar_create, calendar_delete]
[Designs test cases:]
tests/calendar-events.yaml:
- list_upcoming_events (expect: array, count_gte 0)
- search_by_keyword (expect: contains search term)
- invalid_date_range (expect: error status)
tests/calendar-mutations.yaml:
- create_event (expect: success, returns event_id)
- delete_nonexistent (expect: error, contains "not found")
The skill teaches Claude:
Your project provides:
name: Feature Tests
description: What these tests validate
# Optional: defaults applied to all tests
defaults:
tool: my_tool_name
timeout: 5000
tests:
- name: test_case_name
description: Human-readable purpose
tool: tool_name # Override default if needed
params:
action: search
query: "test input"
expect:
contains: "expected substring"
not_contains: "should not appear"
status: success
| Rule | Description | Example |
|---|---|---|
contains | Response contains string | contains: "from:john" |
not_contains | Response doesn't contain | not_contains: "error" |
matches | Regex pattern match | matches: "after:\\d{4}" |
json_path |
See references/validation-rules.md for complete documentation.
Testing agents inherit MCP tools from the session. Create an agent that:
CRITICAL : Do NOT specify a tools field if you need MCP access. When you specify ANY tools, it becomes an allowlist and "*" is interpreted literally (not as a wildcard). Omit tools entirely to inherit ALL tools from the parent session.
---
name: my-tester
description: |
Tests [domain] functionality. Reads YAML test specs and validates responses.
Use when: testing after changes, running regression tests.
# tools field OMITTED - inherits ALL tools from parent (including MCP)
model: sonnet
---
# [Domain] Tester
## How It Works
1. Find test specs: `tests/*.yaml`
2. Parse and execute each test
3. Validate responses
4. Report pass/fail summary
## Test Spec Location
tests/
├── feature-a.yaml
├── feature-b.yaml
└── results/
└── YYYY-MM-DD-HHMMSS.md
## Execution
For each test:
1. Call tool with params
2. Capture response
3. Apply validation rules
4. Record PASS/FAIL
## Reporting
Save results to `tests/results/YYYY-MM-DD-HHMMSS.md`
See templates/test-agent.md for complete template.
Test results are saved as markdown for git history:
# Test Results: feature-name
**Date**: 2026-02-02 14:30
**Commit**: abc1234
**Summary**: 8/9 passed (89%)
## Results
- test_basic_search - PASSED (0.3s)
- test_with_filter - PASSED (0.4s)
- test_edge_case - FAILED
## Failed Test Details
### test_edge_case
- **Expected**: Contains "expected value"
- **Actual**: Response was empty
- **Params**: `{ action: search, query: "" }`
Save to: tests/results/YYYY-MM-DD-HHMMSS.md
# tests/search.yaml
name: Search Tests
defaults:
tool: my_search_tool
tests:
- name: basic_search
params: { query: "hello" }
expect: { status: success, count_gte: 0 }
- name: filtered_search
params: { query: "hello", filter: "recent" }
expect: { contains: "results" }
Copy templates/test-agent.md and customise for your domain.
"Run the search tests"
"Test the API after my changes"
"Run regression tests for gmail-mcp"
Results saved to tests/results/. Commit them for history:
git add tests/results/
git commit -m "Test results: 8/9 passed"
Run multiple test agents simultaneously to speed up large test suites:
"Run these test suites in parallel:
- Agent 1: tests/auth/*.yaml
- Agent 2: tests/search/*.yaml
- Agent 3: tests/api/*.yaml"
Each agent:
Why parallel agents?
Batching strategy:
For MCP servers, the testing agent inherits configured MCPs:
# Configure MCP first
claude mcp add --transport http gmail https://gmail.mcp.example.com/mcp
# Then test
"Run tests for gmail MCP"
Example MCP test spec:
name: Gmail Search Tests
defaults:
tool: gmail_messages
tests:
- name: search_from_person
params: { action: search, searchQuery: "from John" }
expect: { contains: "from:john" }
- name: search_with_date
params: { action: search, searchQuery: "emails from January 2026" }
expect: { matches: "after:2026" }
For REST APIs, use Bash tool:
name: API Tests
defaults:
timeout: 5000
tests:
- name: health_check
command: curl -s https://api.example.com/health
expect: { contains: "ok" }
- name: get_user
command: curl -s https://api.example.com/users/1
expect:
json_path: "$.name"
type: string
For browser automation, use Playwright tools:
name: UI Tests
tests:
- name: login_page_loads
steps:
- navigate: https://app.example.com/login
- snapshot: true
expect: { contains: "Sign In" }
- name: form_submission
steps:
- navigate: https://app.example.com/form
- type: { ref: "#email", text: "test@example.com" }
- click: { ref: "button[type=submit]" }
expect: { contains: "Success" }
search_with_date_filter not test1| Scenario | Use This | Use Traditional Testing |
|---|---|---|
| MCP server validation | Yes | No |
| API integration | Yes | Complement with unit tests |
| Browser workflows | Yes | Complement with component tests |
| Unit testing | No | Yes (Jest/Vitest) |
| Component testing | No | Yes (Testing Library) |
| Type checking | No | Yes (TypeScript) |
templates/test-spec.yaml - Generic test spec templatetemplates/test-agent.md - Testing agent templatereferences/validation-rules.md - Complete validation rule referenceWeekly Installs
158
Repository
GitHub Stars
650
First Seen
Feb 2, 2026
Security Audits
Gen Agent Trust HubFailSocketWarnSnykWarn
Installed on
claude-code128
opencode108
gemini-cli100
replit97
codex94
cursor87
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
152,900 周安装
| Check value at JSON path |
json_path: "$.results[0].name" |
equals | Exact value match | equals: "success" |
status | Check success/error | status: success |
count_gte | Array length >= N | count_gte: 1 |
count_eq | Array length == N | count_eq: 5 |
type | Value type check | type: array |