关于 test-suite-ensure
test-suite-ensure 是用于项目测试覆盖的技能,可识别技术栈和测试框架,并为现有逻辑生成、运行单元测试;也可在检测到 E2E 框架时处理端到端测试。工作流可按变更文件限定范围,并选择建议或强制模式。
主要功能
- 01识别技术栈与测试框架
- 02按需搭建测试框架
- 03为逻辑代码生成并补充单元测试
- 04运行单元测试并处理失败
- 05检测并可选运行 E2E 测试
适用场景
- 01为缺少测试配置的项目搭建测试框架
- 02为工作流修改的逻辑文件补充测试
- 03检查现有项目的逻辑代码测试覆盖
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fudesign2008/ open-skills --skill test-suite-ensure安装后在 Claude Code 中输入/test-suite-ensure确认已加载。
详细介绍
确保测试套件
确保当前项目已配置测试套件:检测技术栈和框架,必要时搭建测试脚手架,生成单元测试(必需,仅限逻辑代码),并可选择生成/运行端到端(E2E)测试。
调用约定
- 独立触发:用户说出触发词时,对当前项目运行完整流程
- 由工作流调用:将测试生成范围限定为工作流中已更改的逻辑文件
- 调用前阅读 SKILL.md:工作流必须在每次调用前阅读此文件,绝不能凭记忆调用
工作流模式
工作流调用方必须声明一种模式:
mode=advisory:如果缺少必需的测试脚手架,且用户拒绝搭建,则继续执行,并在报告中提醒逻辑更改尚未生成测试。这不会阻塞流程。mode=mandatory:如果用户拒绝必需的测试脚手架,或单元测试运行失败,则阻止退出执行阶段。解决问题,或等待用户处理后再继续。
独立调用使用完整流程。第 5 阶段中的单元测试失败处理在两种模式下均适用。
与 test-first-discipline 的边界
此技能是事后处理:检测技术栈,为现有逻辑搭建测试脚手架、生成/运行测试,并按照建议或强制模式进行门控。它不负责先写失败测试的顺序。完成 test-suite-ensure 绝不能被描述为满足了 test-first-discipline。两者均在范围内时,宿主应在实现行为期间运行 test-first,然后在之后运行 test-suite-ensure,以补足覆盖率或测试脚手架的缺口。
第 1 阶段:检测技术栈
扫描项目根目录,确定主要语言和框架:
| 文件 | 检测结果 |
|---|---|
package.json | JavaScript / TypeScript |
go.mod | Go |
requirements.txt / pyproject.toml / setup.py | Python |
pom.xml / build.gradle | Java |
Cargo.toml | Rust |
*.csproj / *.sln | C# / .NET |
如果检测到 package.json,进一步识别前端框架:
- 包含
"vite"→ 优先使用 Vitest - 包含
"react"/"vue"/"angular"→ 前端框架(但测试仍仅覆盖逻辑层) - 包含
"next"/"nuxt"→ 服务端渲染框架 - 仅包含
"express"/"fastify"/"koa"等 → 纯 Node.js 后端
第 2 阶段:检测测试框架
根据技术栈检测现有测试框架:
JavaScript / TypeScript:
- 存在
jest.config.js/jest.config.ts,或package.json的devDependencies包含jest→ Jest ✅ - 存在
vitest.config.js/vitest.config.ts,或devDependencies包含vitest→ Vitest ✅ - 已配置
package.json的scripts.test→ 对应的框架 ✅ - 未找到 → 需要搭建测试脚手架(见第 3 阶段)
Python:
- 存在
pytest.ini/setup.cfg [tool:pytest]/pyproject.toml [tool.pytest.ini_options]→ Pytest ✅ devDependencies或requirements*.txt包含pytest→ Pytest ✅- 未找到 → 需要搭建测试脚手架(见第 3 阶段)
Go:
- 内置
go test;检测到go.mod即足够 ✅,无需额外框架
Java:
pom.xml包含junit依赖,或build.gradle包含testImplementation 'junit'→ JUnit ✅
Rust:
- 内置
cargo test,无需额外检测 ✅
阶段 3:框架脚手架(仅当阶段 2 判定为“需要搭建脚手架”时)
根据技术栈选择并安装:
| 技术栈 | 首选方案 | 安装命令 |
|---|---|---|
| TypeScript + Vite 项目 | Vitest | npm install -D vitest @vitest/ui |
| TypeScript / JavaScript 通用项目 | Jest + ts-jest | npm install -D jest ts-jest @types/jest |
| Python | Pytest | pip install pytest pytest-cov |
脚手架搭建步骤:
- 运行安装命令
- 创建最简配置文件(
vitest.config.ts/jest.config.ts/pytest.ini) - 如果
package.json的scripts中没有"test"条目,则添加:- Vitest:
"test": "vitest run" - Jest:
"test": "jest"
- Vitest:
工具限制:✅ 允许使用 Bash 执行安装命令;✅ 允许使用 Write 创建配置文件
阶段 4:单元测试范围判定
范围内(逻辑代码)
以下目录和文件类型在范围内:
services/、utils/、helpers/、lib/、core/、models/、store/、api/- 纯逻辑钩子(
hooks/、composables/中没有 JSX / 模板渲染的钩子) - 工具函数文件(
*.util.ts、*.helper.ts、*.service.ts) - 状态管理逻辑(Vuex / Redux / Zustand / Pinia 存储逻辑层)
- 数据处理、格式化、验证和转换函数
范围外(UI 层 — 不进行单元测试)
以下目录和文件类型在范围外:
components/、views/、pages/、layouts/、screens/- 含 JSX / 模板渲染的文件:
.tsx、.vue、.svelte、.jsx *.stories.tsx、*.stories.ts(Storybook)__mocks__/、fixtures/(测试辅助文件)- 样式文件(
*.css、*.scss、*.less)
范围优先级
- 由工作流调用时:优先覆盖工作流变更文件中的逻辑文件;如果没有提供,则全局扫描
- 独立运行时:全局扫描,优先处理没有对应测试文件的逻辑文件
阶段 5:单元测试生成与执行【必需,阻塞】
生成原则
- 每个逻辑文件对应一个测试文件;如果测试文件已存在,则追加缺失用例,不要覆盖
- 每个函数/方法至少覆盖三种用例:
- 正常路径(正常输入)
- 边界值(空值、零、极端输入)
- 错误路径(抛出异常、无效输入)
- 使用框架原生断言;不要引入额外的断言库
测试文件命名约定
| 框架 | 命名约定 | 建议位置 |
|---|---|---|
| Jest / Vitest | <name>.spec.ts 或 <name>.test.ts | 与源文件同目录,或位于 __tests__/ |
| Pytest | test_<name>.py 或 <name>_test.py | tests/ 目录或与源文件同目录 |
| Go | <name>_test.go | 与源文件同目录(同一包) |
| JUnit | <Name>Test.java | src/test/java/ 中与包路径对应的位置 |
运行
对于 Node / JavaScript / TypeScript 项目,运行前应将 Node 版本与项目声明的版本保持一致——调用
node-version-discipline技能(它会检查完整链路.nvmrc/.node-version/.tool-versions/volta/engines.node/ CI 配置;如果没有声明版本,则询问用户)。使用错误的 Node 版本运行测试会导致误通过 / 误失败。其他技术栈(Python / Go / Rust / Java)不受影响。
# JavaScript / TypeScript (Jest)
npm test -- --passWithNoTests
# JavaScript / TypeScript (Vitest)
npx vitest run
# Python
pytest --tb=short
# Go
go test ./...
# Rust
cargo test
# Java (Maven)
mvn test
# Java (Gradle)
./gradlew test
阻塞条件
单元测试失败(退出代码非零)时:
- 输出失败测试列表(文件名 + 测试名称 + 错误消息)
- 尝试自动修复(最多 2 轮:分析错误 → 修改测试代码或实现)
- 2 轮后仍失败:停止并等待用户介入,输出:
- 失败原因分析
- 建议的修复方向(修改实现 / 调整测试预期 / 手动添加模拟对象)
阶段 6:E2E 测试检测与执行【可选】
检测 E2E 支持
| 配置文件 | 框架 |
|---|---|
playwright.config.ts / playwright.config.js | Playwright |
cypress.config.ts / cypress.config.js | Cypress |
nightwatch.conf.js / nightwatch.conf.ts | Nightwatch |
wdio.conf.js / wdio.conf.ts | WebdriverIO |
- 已检测到 → 继续生成并执行 E2E 测试
- 未检测到 → 静默跳过,并在输出中注明:"未检测到 E2E 框架,跳过"
E2E 测试生成原则(仅在检测到框架时)
- 优先覆盖核心用户流程(登录/注册、主要业务操作、关键页面导航)
- 由工作流调用时,重点覆盖受此更改影响的页面/流程
- 如果已有 E2E 用例,追加,不要覆盖
运行
# Playwright
npx playwright test
# Cypress (headless mode)
npx cypress run
E2E 失败时:输出失败截图路径(如果有)和失败原因;不要阻塞主流程(E2E 是可选项)。
输出格式
【test-suite-ensure Results】
- Tech Stack: ... (e.g. TypeScript + Vite)
- Test Framework: Existing <name> / Newly installed <name> (with config file path)
- Unit Tests:
- In-scope logic files: X
- New test files: X, Appended cases: X
- Run result: ✅ X passed, 0 failed / ❌ X failed (list failed tests)
- E2E Tests:
- Detection: Detected <framework name> / Not detected, skipped
- Run result: ✅ X passed / ❌ X failed (with screenshot path) / Skipped
常见错误
| 错误 | 后果 | 修复方法 |
|---|---|---|
| 将 UI 组件文件纳入单元测试范围 | 生成无意义的渲染测试,维护成本高 | 严格遵循排除规则,仅覆盖逻辑层 |
| 框架已存在时重新安装 | 依赖版本冲突 | 第 2 阶段检测到框架后,跳过第 3 阶段 |
| 覆盖现有测试文件 | 丢失已有测试逻辑 | 始终使用追加模式,绝不覆盖 |
| 单元测试失败 2 轮或以上后仍继续 | 交付时测试仍然失败 | 必须在 2 轮后停止,等待用户介入 |
| E2E 失败时阻塞主流程 | E2E 是可选项,不应作为硬性门槛 | E2E 失败时仅输出警告,不阻塞 |
| 工作流调用时忽略已更改文件列表 | 测试覆盖范围过广或遗漏关键更改 | 优先以已更改文件为范围,然后再全局扩展 |