单元测试:gtest 与 HTTP 接口测试
官方测试组件 gtest(github.com/gogf/gf/v2/test/gtest)是对标准库 testing 的轻量扩展:它不引入新框架,只补齐“测试用例分组 + 常用断言”,官方文档说明复杂场景还可以搭配 testify、goconvey 使用。本章介绍 gtest 基础写法,并给出 HTTP 接口层测试的常用做法。
基本概念
gtest.C(t, func(t *gtest.T){...})创建一个测试分组(Case),一个Test*函数可包含多个C。C内断言失败会输出统一错误信息并终止当前分组,不影响其他分组继续执行。- 断言方法:
Assert(宽松比较)、AssertEQ(连类型一起比)、AssertNE、AssertNil、AssertGT/GE/LT/LE、AssertIN/NI(v2.9 起支持 map 键判断)等。 - 测试包既可用
包名_test,也可直接用包名(后者才能访问包内私有方法)。
gtest 基本断言
package service_test
import (
"testing"
"github.com/gogf/gf/v2/test/gtest"
)
// 被测函数:字符串反转
func Reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
func Test_Reverse(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.Assert(Reverse("hello"), "olleh") // 宽松:值相等即可
t.AssertEQ(Reverse(""), "") // 严格:类型也相等
t.Assert(Reverse("中文"), "文中") // 多字节安全
})
gtest.C(t, func(t *gtest.T) {
// 每个 C 之间相互隔离,失败互不影响
t.AssertIN("a", []string{"a", "b"})
t.AssertNil(nil)
})
}
命令行执行 go test ./... 即可。gtest 还提供 DataPath/DataContent 方便读取测试包 testdata 目录下的数据文件。
HTTP 接口层测试
接口层测试的关键是“让服务真实跑起来”。规范路由的处理器与 net/http 耦合在 ghttp.Request 上,因此常用做法是:测试内启动一个真实 Server(随机端口),再用 HTTP 客户端请求并断言返回。以下代码使用的组件(g.Server 启动/停止、g.Client 发请求)均有官方文档支持,具体组装方式以官方文档 goframe.org 为准:
package main
import (
"testing"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/test/gtest"
)
func Test_HelloAPI(t *testing.T) {
s := g.Server("test-server")
s.BindHandler("/hello", func(r *ghttp.Request) {
r.Response.WriteJson(g.Map{"code": 0, "data": "hi " + r.Get("name").String()})
})
s.SetPort(28080)
s.Start()
defer s.Shutdown()
gtest.C(t, func(t *gtest.T) {
c := g.Client()
c.SetPrefix("http://127.0.0.1:28080")
content := c.GetContent(r.Context(), "/hello?name=john")
t.Assert(content, `{"code":0,"data":"hi john"}`)
})
}
说明:r.Context() 在测试中可取 context.Background();若要复用标准库的 httptest,可以把它用于被测的、独立的 http.Handler 或 http.HandlerFunc 组件上(ghttp 的服务路由本身由框架管理,不走 httptest.NewServer),两种工具的适用边界需要分清。
注意点
- 单元测试要“快而稳”:尽量测纯函数与单层逻辑,数据库依赖用真实测试库并在用例间清理数据。
- 接口测试的端口要避开开发环境占用,或直接使用框架支持的随机端口能力。
- 断言失败的报错带堆栈定位,别吞错误、别在断言前
println大对象。 - 与 CI 结合时注意测试配置与本地配置分离(如独立 test 数据库、关闭外部依赖)。
小结
gtest 负责“好写断言、分组隔离”,HTTP 冒烟测试负责“验证路由与序列化整体正确”。两者结合,业务函数与接口层都能得到覆盖;更复杂场景再引入 testify/goconvey。全部接口以官方文档 goframe.org 为准。