测试与部署
1. Go测试基础
Go内置测试框架,测试文件以_test.go结尾:
// math.go
func Add(a, b int) int {
return a + b
}
// math_test.go
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("预期 5, 得到 %d", result)
}
}
// 运行测试
// go test -v ./...
2. 表格驱动测试
表格驱动测试是Go中的常见模式:
func TestAddTable(t *testing.T) {
tests := []struct {
name string
a, b int
expect int
}{
{"正数相加", 2, 3, 5},
{"负数相加", -1, -1, -2},
{"零值相加", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expect {
t.Errorf("预期 %d, 得到 %d", tt.expect, result)
}
})
}
}
3. HTTP测试
使用net/http/httptest测试HTTP处理器
func TestHelloHandler(t *testing.T) {
req, err := http.NewRequest("GET", "/hello", nil)
if err != nil {
t.Fatal(err)
}
rr := httptest.NewRecorder()
handler := http.HandlerFunc(helloHandler)
handler.ServeHTTP(rr, req)
if status := rr.Code; status != http.StatusOK {
t.Errorf("handler 返回错误状态码: 得到 %v 预期 %v",
status, http.StatusOK)
}
expected := "Hello, World!"
if rr.Body.String() != expected {
t.Errorf("handler 返回意外内容: 得到 %v 预期 %v",
rr.Body.String(), expected)
}
}
测试Gin路由
func setupRouter() *gin.Engine {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.String(200, "pong")
})
return r
}
func TestPingRoute(t *testing.T) {
router := setupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/ping", nil)
router.ServeHTTP(w, req)
if w.Code != 200 {
t.Error("响应状态码错误")
}
if w.Body.String() != "pong" {
t.Error("响应内容错误")
}
}
4. 性能测试
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(1, 2)
}
}
// 运行性能测试
// go test -bench=. -benchmem
5. 基本部署策略
构建可执行文件
# 构建当前包
go build -o app
# 跨平台构建
GOOS=linux GOARCH=amd64 go build -o app-linux
GOOS=windows GOARCH=amd64 go build -o app.exe
使用Docker部署
# Dockerfile
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o app .
FROM alpine
WORKDIR /app
COPY /app/app .
EXPOSE 8080
CMD ["./app"]
# 构建镜像
docker build -t myapp .
# 运行容器
docker run -d -p 8080:8080 myapp
部署到云平台
- 传统部署:将二进制文件上传到服务器,使用systemd或supervisor管理进程
- 容器化部署:使用Docker + Kubernetes或云平台容器服务
- Serverless:适用于API服务,如AWS Lambda + API Gateway
6. 持续集成示例(.github/workflows/go.yml)
name: Go
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.19
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...
- name: Lint
uses: golangci/golangci-lint-action@v2
with:
version: v1.46.2
提示:良好的测试覆盖率是代码质量的保证,而自动化部署流程可以减少人为错误。建议从项目早期就建立这些实践。
