Go Web 编程实战Go Web 编程实战
首页
课程导读
首页
课程导读
  • 课程导读
  • 课程目录

    • Go基础语法精要
    • Web基础与HTTP处理
    • Gin框架入门
    • 路由与中间件
    • 数据库操作
    • 模板渲染
    • 错误处理与日志
    • 测试与部署
    • 高级中间件模式
    • 微服务架构
    • 性能优化
    • 安全最佳实践
    • 项目结构与代码组织

测试与部署

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 --from=builder /app/app .
EXPOSE 8080
CMD ["./app"]
# 构建镜像
docker build -t myapp .

# 运行容器
docker run -d -p 8080:8080 myapp

部署到云平台

  1. 传统部署:将二进制文件上传到服务器,使用systemd或supervisor管理进程
  2. 容器化部署:使用Docker + Kubernetes或云平台容器服务
  3. 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

提示:良好的测试覆盖率是代码质量的保证,而自动化部署流程可以减少人为错误。建议从项目早期就建立这些实践。

Prev
错误处理与日志
Next
高级中间件模式