Golang接口测试及测试覆盖率

发布 : 2019-06-27 分类 : 笔记

本文 go 版本 1.12.5, 在 go mod 下 当前项目名称 goshop

1. 书写代码

  1. Handler 代码 goshop/app/api/manager/customer/customer.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package customer

    import (
    ...
    )

    // GetCustomersList 获取用户列表
    func GetCustomersList(c *gin.Context) {

    users := []model.Customer{}
    var count uint

    model.DB.Limit(4).Offset(2).Find(&users)
    model.DB.Model(&model.Customer{}).Count(&count)
    // 指针引用小坑
    for idx := range users {
    item := &users[idx]
    model.DB.Model(&item).Related(&item.CustomerInfo)
    }

    fmt.Printf("%+v", users)

    c.JSON(200, gin.H{
    "status": 0,
    "msg": "",
    "data": users,
    "count": count,
    })
    }
  2. 路由代码 goshop/app/routes/api/manager.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package api

    import (
    "goshop/app/api/manager/customer"
    "goshop/app/api/manager/media"

    //"fmt"
    "github.com/gin-gonic/gin"
    )

    // ManagerRoutes 后台管理路由
    func ManagerRoutes(app *gin.Engine) {
    managerGroup := app.Group("api/manager")
    ...
    managerGroup.GET("/customer/:id", customer.GetCustomer)
    ...
    }
  3. 测试代码 goshop/main_test.go

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    package main

    import (
    "encoding/json"
    "io/ioutil"
    "net/http"
    "net/http/httptest"
    "testing"
    )

    type responseJSON struct {
    msg string
    status int
    data interface{}
    }

    type apiSuite struct {
    url string
    data responseJSON
    }
    // 启动主函数,只启动一次
    func TestMain(m *testing.M) {
    m.Run()
    }

    // 示例,用简单封装 GET 请求
    func requetsGetTest(url string) (*httptest.ResponseRecorder, *http.Request) {
    req := httptest.NewRequest("GET", url, nil)
    w := httptest.NewRecorder()
    return w, req
    }

    // 测试接口,
    func TestGetCustomer(t *testing.T) {
    type api struct {
    url string
    result map[string]string
    }

    apiList := []apiSuite{
    apiSuite{"/api/manager/customer/-1", responseJSON{msg: "用户不存在"}},
    }

    for _, v := range apiList {
    w, req := requetsGetTest(v.url)
    // 构建请求
    app.ServeHTTP(w, req)

    // 获取返回结果
    result := w.Result()
    // 解析结果
    body, _ := ioutil.ReadAll(result.Body)
    // 关闭结果流
    result.Body.Close()
    // 定义响应结构
    resJSON := &responseJSON{}
    // 解析响应 json
    json.Unmarshal(body, &resJSON)

    // 如果不等于 200 响应码,则记录并请求下一次
    if result.StatusCode != 200 || resJSON.status != 0 {
    t.Errorf("接口 %s 请求失败,%s", v.url, resJSON.msg)
    continue
    }
    }
    }

2. 查看覆盖率

上一篇文章中, 写入了简单的单库测试方法. 与本文基本相似
增加参数 -coverpkg 用于统计当前测试程序,覆盖了哪些指定的源码模块

1
2
go test -v -coverprofile=cover.out 
// 默认测试的 main 模块的 main 函数

因此,需要指定测试的 Hander 模块及路由模块

1
go test -v -coverptofile=cover.out -coverpkg .,app/api/manager/customer,app/routes/api

此时输出的就是当前想要测试到的模块及文件
由于项目开发会造成大量文件,每次输入很长的测试命令,因此将其写入 Makefile 中借助 make 命令完成简化

1
2
3
4
5
6
7
....
输出详细测试及测试二进制文件
outtest:
go test -v -coverptofile=cover.out -coverpkg .,app/api/manager/customer,app/routes/api -o main.test
# 展示 html 报告
showcover:
go tool cover -html=cover.out
本文作者 : 萧逸雨
原文链接 : http://qiubo.ink/2019/06/27/Golang接口测试及测试覆盖率/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!