测试生成
wescode 利用 AI 和代码知识图谱自动生成高质量的测试代码,支持单元测试、集成测试和边界用例,并提供覆盖率分析和 TDD 工作流支持。
单元测试
自动生成
选中函数或在 Chat 面板中指定目标即可生成单元测试:
# 为当前文件生成测试
/test generate
# 为指定函数生成测试
/test generate --func ParseConfig
# 为指定文件生成测试
/test generate internal/service/user.go
生成策略
wescode 生成测试时会分析:
- 函数签名:输入参数类型和返回值类型
- 函数逻辑:条件分支、循环、错误路径
- 依赖关系:外部依赖自动生成 Mock
- 调用上下文:通过 CKG 分析实际调用方式
- 项目约定:遵循项目已有的测试风格
生成示例
对于以下 Go 函数:
func ParseDuration(s string) (time.Duration, error) {
if s == "" {
return 0, fmt.Errorf("empty duration string")
}
return time.ParseDuration(s)
}
wescode 会生成:
func TestParseDuration(t *testing.T) {
tests := []struct {
name string
input string
want time.Duration
wantErr bool
}{
{
name: "valid duration seconds",
input: "30s",
want: 30 * time.Second,
},
{
name: "valid duration minutes",
input: "5m",
want: 5 * time.Minute,
},
{
name: "empty string",
input: "",
wantErr: true,
},
{
name: "invalid format",
input: "abc",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseDuration(tt.input)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
assert.Equal(t, tt.want, got)
})
}
}
测试风格适配
wescode 会自动识别并匹配项目的测试风格:
| 检测项 | 示例 |
|---|---|
| 测试框架 | testing / testify / gomega |
| 命名风格 | TestXxx / Test_xxx |
| 组织方式 | 表驱动测试 / 独立用例 |
| Assert 库 | assert / require / 标准库 |
| Mock 方式 | gomock / testify/mock / 手写 |
集成测试
生成集成测试
对于涉及数据库、HTTP 或外部服务的代码:
# 生成 HTTP handler 集成测试
/test generate --type integration internal/handler/user.go
# 生成数据库操作集成测试
/test generate --type integration internal/repo/user.go
测试基础设施
wescode 会根据需要自动生成测试辅助代码:
- 测试数据库:使用
testcontainers或内存数据库 - HTTP 测试服务:
httptest.Server配置 - Mock 服务:外部依赖的 Mock 实现
- 测试 Fixtures:测试数据文件
集成测试示例
func TestUserHandler_Create(t *testing.T) {
// 设置测试数据库
db := setupTestDB(t)
defer db.Close()
// 初始化依赖
repo := NewUserRepository(db)
svc := NewUserService(repo)
handler := NewUserHandler(svc)
// 创建测试服务器
router := setupRouter(handler)
srv := httptest.NewServer(router)
defer srv.Close()
// 执行测试
body := `{"name": "Alice", "email": "alice@example.com"}`
resp, err := http.Post(srv.URL+"/users", "application/json",
strings.NewReader(body))
require.NoError(t, err)
assert.Equal(t, http.StatusCreated, resp.StatusCode)
// 验证数据库状态
user, err := repo.GetByEmail(context.Background(), "alice@example.com")
require.NoError(t, err)
assert.Equal(t, "Alice", user.Name)
}
测试覆盖
覆盖率分析
wescode 集成了测试覆盖率分析工具:
# 查看当前覆盖率
/test coverage
# 查看指定包的覆盖率
/test coverage internal/service/
# 查看未覆盖的代码行
/test coverage --uncovered
覆盖率可视化
覆盖率信息直接显示在编辑器中:
- 绿色背景:已被测试覆盖的代码行
- 红色背景:未被覆盖的代码行
- 黄色背景:部分覆盖(如条件分支只覆盖了一个方向)
补充覆盖
针对未覆盖的代码自动生成补充测试:
# 为未覆盖的分支生成测试
/test fill-coverage internal/service/user.go
# 提升到目标覆盖率
/test fill-coverage --target 80%
覆盖率报告
覆盖率报告:internal/service/
┌─────────────────────┬──────┬──────┬──────┐
│ 文件 │ 语句 │ 分支 │ 函数 │
├─────────────────────┼──────┼──────┼──────┤
│ user.go │ 85% │ 72% │ 90% │
│ auth.go │ 92% │ 88% │ 100% │
│ config.go │ 65% │ 50% │ 80% │
├─────────────────────┼──────┼──────┼──────┤
│ 总计 │ 81% │ 70% │ 90% │
└─────────────────────┴──────┴──────┴──────┘
未覆盖的关键路径:
config.go:45-52 错误处理分支
config.go:78-85 默认值回退逻辑
user.go:120-128 并发安全检查
边界用例
自动识别边界条件
wescode 通过代码分析自动识别需要测试的边界条件:
- 空值/零值:nil、空字符串、0、空切片
- 极端值:最大/最小整数、超长字符串
- 特殊字符:Unicode、转义字符、SQL 注入尝试
- 并发场景:竞态条件、死锁
- 资源边界:内存限制、超时、文件系统满
- 错误路径:网络错误、权限错误、格式错误
边界测试生成
# 生成边界用例
/test boundaries ParseConfig
# 生成模糊测试
/test fuzz ParseConfig
# 生成并发安全测试
/test concurrent UserCache
边界测试示例
func TestParseConfig_Boundaries(t *testing.T) {
tests := []struct {
name string
input string
wantErr bool
}{
{"nil input", "", true},
{"whitespace only", " \n\t ", true},
{"max length", strings.Repeat("a", 1<<20), true},
{"unicode content", "配置=值", false},
{"special chars", `key="val\"ue"`, false},
{"duplicate keys", "key=1\nkey=2", true},
{"circular reference", "a=${b}\nb=${a}", true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := ParseConfig([]byte(tt.input))
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
TDD 流程
TDD 模式
wescode 支持测试驱动开发工作流:
# 进入 TDD 模式
/tdd start
# 描述需求,AI 先生成测试
/tdd "实现一个 LRU 缓存,支持 Get、Put 和 TTL 过期"
TDD 工作流步骤
-
Red(编写失败测试)
- 根据需求描述生成测试用例
- 运行测试确认失败(验证测试有效性)
-
Green(编写最小实现)
- AI 生成满足测试的最小实现代码
- 运行测试确认通过
-
Refactor(重构优化)
- AI 建议可能的重构方向
- 每次重构后自动运行测试确保不回退
TDD 示例会话
用户:/tdd "实现邮箱地址验证函数"
wescode:好的,开始 TDD 流程。
🔴 Step 1 - 生成测试:
func TestValidateEmail(t *testing.T) {
// 有效地址
assert.True(t, ValidateEmail("user@example.com"))
assert.True(t, ValidateEmail("user.name@domain.co"))
// 无效地址
assert.False(t, ValidateEmail(""))
assert.False(t, ValidateEmail("user@"))
assert.False(t, ValidateEmail("@domain.com"))
assert.False(t, ValidateEmail("user domain.com"))
}
测试运行结果:FAIL(函数尚未实现)
🟢 Step 2 - 需要我生成实现代码吗?
持续测试
在 TDD 模式下,wescode 提供持续测试反馈:
- 保存文件自动运行相关测试
- 测试结果实时显示在状态栏
- 失败测试自动聚焦到失败点
- 覆盖率变化实时更新
配置选项
# .wescode/test.yaml
test:
# 测试框架偏好
framework: "testify"
# 默认测试类型
default-type: "unit"
# Mock 生成方式
mock-style: "gomock"
# 覆盖率目标
coverage-target: 80
# 排除目录
exclude:
- "vendor/"
- "*.generated.go"
- "testdata/"
常见问题
Q: 生成的测试质量不高?
A: 确保 CKG 索引已完成,这样 AI 可以了解函数的实际使用模式。也可以在 Chat 中提供额外上下文来引导生成。
Q: Mock 生成不正确?
A: 检查接口定义是否完整。wescode 需要明确的接口定义来生成正确的 Mock。可以先用 /refactor extract-interface 提取接口。
Q: 如何处理需要外部服务的测试?
A: 使用 --type integration 标志,wescode 会自动使用 testcontainers 或 Mock 服务来处理外部依赖。