Go集成测试是用go test运行的普通测试,关键在验证多组件协同工作;需保留真实依赖如SQLite、Redis、HTTP server,通过构建标签-integration隔离执行,用httptest和内存DB控制成本。
Go 语言的集成测试没有特殊语法或专属命令,它本质上是用 go test 运行的普通测试,关键在于测试范围和依赖处理——它要验证多个组件(如 HTTP handler、数据库、外部服务)协同工作是否正常。
单元测试聚焦单个函数或方法,常通过接口 mock 隔离外部依赖;集成测试则有意保留真实依赖(如 SQLite 文件、本地 Redis、HTTP server),观察端到端行为。例如:测试一个用户注册 API,需启动真实 handler、连接真实数据库、检查插入结果,而不是只测某个 service 方法的返回值。
推荐将集成测试放在独立文件中(如 user_integration_test.go),并用构建标签控制执行:
//go:build integration(Go 1.17+)或 // +build integration(旧版)TestXxx 开头,但建议命名含 Integration,如 TestUserRegistrationIntegration
go test -tags=integration ./...,避免日常开发误跑耗时或有副作用的测试集成测试需要稳定、可重置的环境:
file:memdb?mode=memory&cache=shared)或每次测试前清空测试表(TRUNCATE users)httptest.NewServer 启动真实 handler,获取 server.URL 发起请求,测试完调 server.Close()
gomock 或轻量 HTTP stub(如 testify/httpmock)模拟响应,保持可控性假设有一个简单 HTTP handler 写入数据库:
func TestUserCreateIntegration(t *testing.T) {
db, _ := sql.Open("sqlite3", "test.db")
defer os.Remove("test.db") // 清理
defer db.Close()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 实际业务逻辑,写入 db
})
server := httptest.NewServer(handler)
defer server.Close()
resp, _ := http.Post(server.URL+"/users", "application/json", strings.NewReader(`{"name":"alice"}`))
if resp.StatusCode != 201 {
t.Fatal("expected 201")
}
}
注意:真实项目中应封装 DB 初始化、表迁移、清理逻辑,避免重复代码。
基本上就这些。集成测试不是越重越好,关键是覆盖关键路径、快速失败、环境干净。合理用标签隔离、用 httptest 和内存 DB
控制成本,就能让 Go 的集成测试既可靠又实用。