iceleaf916/my-cc-plugins
udcp-skills
January 22, 2026
Select agents to install to:
npx add-skill https://github.com/iceleaf916/my-cc-plugins/blob/main/udcp-skills/skills/go-test-standards/SKILL.md -a claude-code --skill go-test-standardsInstallation paths:
.claude/skills/go-test-standards/# Golang 单元测试规范
## 一、需要遵循的单元测试理论
### 1.1 每个测试单元逻辑上分为四个阶段(可以用阶段名作为注释分割)
| 阶段 | 说明 |
|------|------|
| **Setup** | 准备测试所需的数据和环境 |
| **Exercise** | 执行被测试的代码 |
| **Verify** | 验证执行结果是否符合预期 |
| **Teardown** | 清理测试环境和数据 |
### 1.2 测试替身使用原则
- 尽可能使用 stub 类型,而不是 mock。为 stub 对象命名时应带有 stub 关键字而不是 mock关键字。
- 针对全局函数的模拟考虑使用 [monkey patching](https://github.com/agiledragon/gomonkey)
## 二、单测代码规范
### 2.1 框架与断言库
Go 项目必须使用以下工具:
- **ginkgo** - BDD 测试框架
- **gomega** - 断言库
**注意事项:**
- ginkgo 可以使用 . 导入。gomega 不要使用 . 导入,而且禁止使用 `Ω` 别名。
- 测试套件注册入口单独写到 `suite_test.go`。
- 被测试文件包为 `abc`,则测试文件属于 `abc_test` 包。
### 2.2 数据访问层测试模板
```go
package db_test
import (
"fmt"
"reflect"
"testing"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
dockertest "github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)
const (
dbName = "test"
dbPwd = "test"
)
func TestDB(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Db Test Suite", Label("repo", "store/db"))
}
var (
Db *gorm.DB
cleanupDocker func()
)
var _ = BeforeSuite(func() {
Db, cleanupDocker = setupGormWithDocker()
})
var _ = AfterSuite(func() {
cleanupDocker()
})
var _ = BeforeEach(func() {
Except(cleanDatabase(Db, dbName)).To(Succeed())
})
func setupGormWithDocker() (*gorm.DB, func()) {
pool, err := dockertest.NewPool("")
chk(err)
runDockerOpt := &dockertest.RunOptions{
Repository: "hub.deepin.com/library/mariadb",
Tag: "10.3.35",
Env: []string{"MARIADB_DATABASE=" + dbName, "MARIADB_ROOT_PASSWORD=" + dbPwd},
}
fnConfig := func(config *docker.HostConfig) {
config.AutoRemove = true
config.RestartPolicy = docker.NeverRestart()
}
resource, err := pool.RunWithOptions(runDockerOpt, fnConfig)
chk(err)
fnCleanup := func() {
err := resource.Close()
chk(err)
}
ds