mcpField
G
generating-unit-tests

generating-unit-tests

github.com/jeremylongshore测试与质量2.9k45 次安装2 天前更新
代码仓库

关于 generating-unit-tests

generating-unit-tests 会分析源代码,并为多种语言和测试框架生成单元测试。它还可运行测试、检查覆盖率并报告尚未覆盖的部分。

主要功能

  1. 01查找缺少测试的源文件
  2. 02生成正常路径与边界测试
  3. 03为外部依赖创建模拟
  4. 04运行测试并检查覆盖率
  5. 05报告覆盖缺口及建议用例

适用场景

  1. 01为尚未测试的函数添加测试
  2. 02覆盖错误条件与边界值
  3. 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.md
references/
README.md
scripts/
README.md

详细介绍

单元测试生成器

概述

通过分析源代码自动生成全面的单元测试,涵盖正常路径、边缘情况、边界条件和错误处理。支持 Jest、Vitest、Mocha(JavaScript/TypeScript)、pytest(Python)、JUnit 5(Java)以及使用 testify 的 Go testing。

前置条件

  • 已安装并配置测试框架(jest、vitest、pytest、junit-jupiter 或 Go testing)
  • 源代码具有清晰的函数签名、类型注解或 JSDoc 注释
  • 已建立测试目录结构(__tests__/、tests/、spec/ 或 *_test.go)
  • 提供模拟库(jest.mock、unittest.mock、Mockito 或 gomock)
  • 已配置用于运行测试的包脚本(npm test、pytest、go test)

说明

  1. 使用 Glob 扫描代码库,查找缺少对应测试文件的源文件(例如,src/utils/parser.ts 没有对应的 __tests__/parser.test.ts)。
  2. 阅读每个未经测试的源文件,并提取:
    • 所有导出的函数和类方法及其签名。
    • 参数类型、返回类型和抛出的异常。
    • 外部依赖(从其他模块导入的内容、第三方库、I/O)。
    • 纯函数与非纯函数的分类。
  3. 为每个函数生成以下类别的测试用例:
    • 正常路径:产生预期输出的有效输入(至少 2 个用例)。
    • 边缘情况:空字符串、空数组、零、负数、null、undefined、最大值。
    • 错误情况:无效类型、缺少必填字段、网络故障、权限错误。
    • 边界值:差一错误、整数溢出、字符串长度限制。
  4. 为所有外部依赖创建模拟声明:
    • 数据库调用返回可预测的测试夹具数据。
    • HTTP 客户端返回状态码可配置的预设响应。
    • 文件系统操作使用内存缓冲区或临时目录。
  5. 遵循项目约定编写测试文件:
    • 匹配现有的测试文件命名模式(*.test.ts、*.spec.js、test_*.py)。
    • 按函数名称使用 describe/context 块组织测试。
    • 使用 beforeEach/afterEach 进行设置和清理。
    • 添加内联注释,说明不明显的测试理由。
  6. 运行生成的测试以验证其通过,然后检查覆盖率,确认目标函数已得到全面测试。
  7. 报告覆盖率缺口,并为未覆盖的分支建议额外测试用例。

输出

  • 放在源文件旁或项目测试目录中的测试文件
  • 外部依赖的模拟/存根文件
  • 显示已测试模块行覆盖率、分支覆盖率和函数覆盖率的覆盖率报告
  • 剩余覆盖率缺口及建议测试用例列表

错误处理

错误原因解决方案
导入时出现 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

评论

支持 Markdown