返回顶部
g

golang-testingGo测试指南

Provides a comprehensive guide for writing production-ready Golang tests. Covers table-driven tests, test suites with testify, mocks, unit tests, integration tests, benchmarks, code coverage, parallel tests, fuzzing, fixtures, goroutine leak detection with goleak, snapshot testing, memory leaks, CI with GitHub Actions, and idiomatic naming conventions. Use this whenever writing tests, asking about testing patterns or setting up CI for Go projects. Essential for ANY test-related conversation in G

作者: admin | 来源: ClawHub
源自
ClawHub
版本
V 0.1.0
安全检测
已通过
145
下载量
免费
免费
0
收藏
概述
安装方式
版本历史

golang-testing

技能名称: golang-testing
详细描述:
角色: 你是一位将测试视为可执行规范的 Go 工程师。你编写测试是为了约束行为,而不是为了达到覆盖率目标。

思维模式: 使用 ultrathink 进行测试策略设计和失败分析。浅层推理会遗漏边界情况,并产生今天能通过但明天就会失效的脆弱测试。

模式:

  • - 编写模式 — 为现有或新代码生成新测试。按顺序处理被测代码;使用 gotests 构建表驱动测试的框架,然后用边界情况和错误路径进行丰富。
  • 审查模式 — 审查 PR 中的测试变更。关注差异:检查新行为的覆盖率、断言质量、表驱动结构以及是否存在不稳定的模式。按顺序进行。
  • 审计模式 — 审计现有测试套件中的漏洞、不稳定或不良模式(顺序依赖的测试、缺少 t.Parallel()、与实现细节耦合)。按关注点最多启动 3 个并行子代理:(1) 单元测试质量和覆盖率缺口,(2) 集成测试隔离和构建标签,(3) goroutine 泄漏和竞态条件。
  • 调试模式 — 测试失败或不稳定。按顺序进行:可靠地复现,隔离失败的断言,在生产代码或测试设置中追踪根本原因。

社区默认。 明确取代 samber/cc-skills-golang@golang-testing 技能的公司技能具有优先权。

Go 测试最佳实践

本技能指导为 Go 应用程序创建可用于生产的测试。遵循这些原则编写可维护、快速且可靠的测试。

最佳实践总结

  1. 1. 表驱动测试必须使用命名的子测试——每个测试用例都需要一个传递给 t.Run 的 name 字段
  2. 集成测试必须使用构建标签(//go:build integration)与单元测试分离
  3. 测试不得依赖于执行顺序——每个测试必须能够独立运行
  4. 独立的测试应尽可能使用 t.Parallel()
  5. 永远不要测试实现细节——测试可观察的行为和公共 API 契约
  6. 包含 goroutine 的包应在 TestMain 中使用 goleak.VerifyTestMain 来检测 goroutine 泄漏
  7. 使用 testify 作为辅助工具,而不是标准库的替代品
  8. 模拟接口,而不是具体类型
  9. 保持单元测试快速(< 1ms),对集成测试使用构建标签
  10. 在 CI 中使用竞态检测运行测试
  11. 包含作为可执行文档的示例

测试结构与组织

文件约定

go
// package_test.go - 同包测试(白盒,可访问未导出内容)
package mypackage

// mypackage_test.go - 测试包中的测试(黑盒,仅公共 API)
package mypackage_test

命名约定

go
func TestAdd(t *testing.T) { ... } // 函数测试
func TestMyStruct_MyMethod(t *testing.T) { ... } // 方法测试
func BenchmarkAdd(b *testing.B) { ... } // 基准测试
func ExampleAdd() { ... } // 示例

表驱动测试

表驱动测试是测试多种场景的惯用 Go 方式。始终为每个测试用例命名。

go
func TestCalculatePrice(t *testing.T) {
tests := []struct {
name string
quantity int
unitPrice float64
expected float64
}{
{
name: 单个商品,
quantity: 1,
unitPrice: 10.0,
expected: 10.0,
},
{
name: 批量折扣 - 100 件,
quantity: 100,
unitPrice: 10.0,
expected: 900.0, // 10% 折扣
},
{
name: 零数量,
quantity: 0,
unitPrice: 10.0,
expected: 0.0,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := CalculatePrice(tt.quantity, tt.unitPrice)
if got != tt.expected {
t.Errorf(CalculatePrice(%d, %.2f) = %.2f, want %.2f,
tt.quantity, tt.unitPrice, got, tt.expected)
}
})
}
}

单元测试

单元测试应该快速(< 1ms)、隔离(无外部依赖)且确定性强。

测试 HTTP 处理器

使用 httptest 结合表驱动模式进行处理器测试。有关请求/响应体、查询参数、头部和状态码断言的示例,请参见 HTTP 测试

使用 goleak 检测 Goroutine 泄漏

使用 go.uber.org/goleak 检测泄漏的 goroutine,特别是对于并发代码:

go
import (
testing
go.uber.org/goleak
)

func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}

要排除特定的 goroutine 栈(对于已知泄漏或库 goroutine):

go
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m,
goleak.IgnoreCurrent(),
)
}

或者按测试进行:

go
func TestWorkerPool(t *testing.T) {
defer goleak.VerifyNone(t)
// ... 测试代码 ...
}

用于确定性 Goroutine 测试的 testing/synctest

实验性: testing/synctest 尚未被 Go 的兼容性保证覆盖。其 API 可能在未来的版本中发生变化。对于稳定的替代方案,请使用 clockwork(参见 Mocking)。

testing/synctest(Go 1.24+)为并发代码测试提供了确定性的时间。时间仅在所有 goroutine 都被阻塞时才会前进,使得执行顺序可预测。

何时使用 synctest 替代真实时间:

  • - 测试包含基于时间操作(time.Sleep、time.After、time.Ticker)的并发代码
  • 当竞态条件需要可复现时
  • 当测试因时序问题而不稳定时

go
import (
testing
time
testing/synctest
github.com/stretchr/testify/assert
)

func TestChannelTimeout(t *testing.T) {
synctest.Run(func(t *testing.T) {
is := assert.New(t)

ch := make(chan int, 1)
go func() {
time.Sleep(50 * time.Millisecond)
ch <- 42
}()

select {
case v := <-ch:
is.Equal(42, v)
case <-time.After(100 * time.Millisecond):
t.Fatal(超时发生)
}
})
}

synctest 中的关键区别:

  • - 当 goroutine 阻塞时,time.Sleep 会立即推进合成时间
  • 当合成时间达到持续时间时,time.After 触发
  • 所有 goroutine 在时间推进前运行到阻塞点
  • 测试执行是确定性的且可重复的

测试超时

对于可能挂起的测试,使用一个带有调用者位置 panic 的超时辅助函数。参见 Helpers

基准测试

→ 有关高级基准测试,请参见 samber/cc-skills-golang@golang-benchmark 技能:b.Loop()(Go 1.24+)、benchstat、从基准测试中分析性能以及 CI 回归检测。

编写基准测试以衡量性能并检测回归:

go
func BenchmarkStringConcatenation(b *testing.B) {
b.Run(加号运算符, func(b *testing.B) {
for i := 0; i < b.N; i++ {
result := a + b + c
_ = result
}
})

b.Run(strings.Builder, func(b *testing.B) {
for i := 0; i < b.N; i++ {
var builder strings.Builder
builder.WriteString(a)
builder.WriteString(b)
builder.WriteString(c)
_ = builder.String()
}
})
}

不同输入大小的基准测试:

go
func BenchmarkFibonacci(b *testing.B) {
sizes := []int{10, 20, 30}
for _, size := range sizes {
b.Run(fmt.Sprintf(n=%d, size), func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Fibonacci(size)
}
})
}
}

并行测试

使用 t.Parallel() 并发运行测试:

go
func TestParallelOperations(t *testing.T) {
tests := []struct {
name string
data []byte
}{
{小数据, make([]byte, 102

标签

skill ai

通过对话安装

该技能支持在以下平台通过对话安装:

OpenClaw WorkBuddy QClaw Kimi Claude

方式一:安装 SkillHub 和技能

帮我安装 SkillHub 和 golang-testing-1776053858 技能

方式二:设置 SkillHub 为优先技能安装源

设置 SkillHub 为我的优先技能安装源,然后帮我安装 golang-testing-1776053858 技能

通过命令行安装

skillhub install golang-testing-1776053858

下载

⬇ 下载 golang-testing v0.1.0(免费)

文件大小: 9.92 KB | 发布时间: 2026-4-14 14:40

v0.1.0 最新 2026-4-14 14:40
Initial release of golang-testing – a comprehensive guide for writing production-grade Go tests.

- Covers table-driven tests, test suites (testify), mocks, unit/integration tests, benchmarks, coverage, parallel/fuzz/fixture tests, goroutine/memory leak detection (goleak), CI, and naming best practices.
- Provides clear best practices and idioms for reliable, maintainable, idiomatic Go tests, including strong guidance on flakiness and coverage.
- Includes detailed organization, naming, and file conventions for Go testing.
- Describes use of `synctest` (Go 1.24+) for deterministic concurrency tests.
- Specifies community conventions and how this skill supersedes similar testing skills.

Archiver·手机版·闲社网·闲社论坛·羊毛社区· 多链控股集团有限公司 · 苏ICP备2025199260号-1

Powered by Discuz! X5.0   © 2024-2025 闲社网·线报更新论坛·羊毛分享社区·http://xianshe.com

p2p_official_large
返回顶部