关于 generating-unit-tests
generating-unit-tests 会分析源代码,并为多种语言和测试框架生成单元测试。它还可运行测试、检查覆盖率并报告尚未覆盖的部分。
主要功能
- 01查找缺少测试的源文件
- 02生成正常路径与边界测试
- 03为外部依赖创建模拟
- 04运行测试并检查覆盖率
- 05报告覆盖缺口及建议用例
适用场景
- 01为尚未测试的函数添加测试
- 02覆盖错误条件与边界值
- 03检查已测模块的覆盖缺口
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jeremylongshore/ tons-of-skills-marketplace --skill generating-unit-tests安装后在 Claude Code 中输入/generating-unit-tests确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/README.mdreferences/README.mdscripts/README.md详细介绍
单元测试生成器
概述
通过分析源代码自动生成全面的单元测试,涵盖正常路径、边缘情况、边界条件和错误处理。支持 Jest、Vitest、Mocha(JavaScript/TypeScript)、pytest(Python)、JUnit 5(Java)以及使用 testify 的 Go testing。
前置条件
- 已安装并配置测试框架(
jest、vitest、pytest、junit-jupiter或 Gotesting) - 源代码具有清晰的函数签名、类型注解或 JSDoc 注释
- 已建立测试目录结构(
__tests__/、tests/、spec/或*_test.go) - 提供模拟库(
jest.mock、unittest.mock、Mockito或gomock) - 已配置用于运行测试的包脚本(
npm test、pytest、go test)
说明
- 使用 Glob 扫描代码库,查找缺少对应测试文件的源文件(例如,
src/utils/parser.ts没有对应的__tests__/parser.test.ts)。 - 阅读每个未经测试的源文件,并提取:
- 所有导出的函数和类方法及其签名。
- 参数类型、返回类型和抛出的异常。
- 外部依赖(从其他模块导入的内容、第三方库、I/O)。
- 纯函数与非纯函数的分类。
- 为每个函数生成以下类别的测试用例:
- 正常路径:产生预期输出的有效输入(至少 2 个用例)。
- 边缘情况:空字符串、空数组、零、负数、
null、undefined、最大值。 - 错误情况:无效类型、缺少必填字段、网络故障、权限错误。
- 边界值:差一错误、整数溢出、字符串长度限制。
- 为所有外部依赖创建模拟声明:
- 数据库调用返回可预测的测试夹具数据。
- HTTP 客户端返回状态码可配置的预设响应。
- 文件系统操作使用内存缓冲区或临时目录。
- 遵循项目约定编写测试文件:
- 匹配现有的测试文件命名模式(
*.test.ts、*.spec.js、test_*.py)。 - 按函数名称使用
describe/context块组织测试。 - 使用
beforeEach/afterEach进行设置和清理。 - 添加内联注释,说明不明显的测试理由。
- 匹配现有的测试文件命名模式(
- 运行生成的测试以验证其通过,然后检查覆盖率,确认目标函数已得到全面测试。
- 报告覆盖率缺口,并为未覆盖的分支建议额外测试用例。
输出
- 放在源文件旁或项目测试目录中的测试文件
- 外部依赖的模拟/存根文件
- 显示已测试模块行覆盖率、分支覆盖率和函数覆盖率的覆盖率报告
- 剩余覆盖率缺口及建议测试用例列表
错误处理
| 错误 | 原因 | 解决方案 |
|---|---|---|
导入时出现 Cannot find module | 测试文件路径与项目模块解析规则不匹配 | 检查 tsconfig.json 中的路径配置和 Jest 配置中的 moduleNameMapper |
| 模拟未拦截调用 | 在模块导入后定义模拟,导致缓存了真实实现 | 将 jest.mock() 调用移到文件顶部,位于所有导入之前 |
| 异步测试超时 | 由于缺少 await 或未处理的拒绝,Promise 始终无法完成 | 在异步调用前添加 await;使用 jest.setTimeout() 增加超时时间 |
| 测试单独运行时通过,但一起运行时失败 | 测试之间泄漏了共享的可变状态 | 在 afterEach 中重置状态;避免使用模块级变量;使用 jest.isolateModules() |
| 首次运行时快照不匹配 | 尚无现有快照基线 | 首次执行时使用 --updateSnapshot 创建基线 |
示例
字符串工具的 Jest 测试:
import { slugify } from '../src/utils/slugify';
describe('slugify', () => {
it('converts spaces to hyphens', () => {
expect(slugify('hello world')).toBe('hello-world');
});
it('lowercases all characters', () => {
expect(slugify('Hello World')).toBe('hello-world');
});
it('removes special characters', () => {
expect(slugify('hello@world!')).toBe('helloworld');
});
it('handles empty string', () => {
expect(slugify('')).toBe('');
});
it('trims leading and trailing whitespace', () => {
expect(slugify(' spaced ')).toBe('spaced');
});
});
数据验证器的 pytest 测试:
import pytest
from myapp.validators import validate_email
class TestValidateEmail:
def test_accepts_valid_email(self):
assert validate_email("[email protected]") is True
def test_rejects_missing_at_sign(self):
assert validate_email("userexample.com") is False
def test_rejects_empty_string(self):
assert validate_email("") is False
def test_rejects_none(self):
with pytest.raises(TypeError):
validate_email(None)
Resources
- Jest documentation: https://jestjs.io/docs/getting-started
- Vitest documentation: https://vitest.dev/guide/
- pytest documentation: https://docs.pytest.org/
- JUnit 5 User Guide: https://junit.org/junit5/docs/current/user-guide/
- Go testing package: https://pkg.go.dev/testing
- AAA pattern (Arrange-Act-Assert):
评论
支持 Markdown