Golang 学习手册
  • 主页
  • 安装
  • 参考资料
  • Q&A
  • 基础
    • Hello,world!
    • 包
    • 变量
    • 常量
    • 类型
      • 整型
      • 浮点型
      • 复数
      • 布尔型
      • 字符
      • 字符串
      • 数组
      • 切片
      • 字典
      • 指针
      • 方法
      • 结构体
      • 接口
      • 自定义类型
    • 语法
      • 判断
      • 循环
      • 错误处理
    • 协程
      • 锁
      • 等待组
      • 通道
      • 上下文
    • 测试与分析
      • 单元测试
      • 性能测试
      • 性能分析
    • 编译
      • 条件编译
      • 交叉编译
  • 高级
    • 存储
      • 键值存储
        • Etcd
    • HTTP
      • http服务基础
      • Websocket
      • 开源框架
        • Beego
        • Echo
        • Gin
        • Iris
        • Revel
        • 框架对比
      • Kubernetes风格API框架
    • RPC
      • RPCX
      • GRPC
      • grpc-gateway
    • 连接分发器
    • TLS加密
    • 链路追踪
      • skywalking
  • 项目管理
    • 代码规范
    • 包管理
    • 文档
      • GoDoc
      • Markdown
      • Swagger
    • 仓库管理
      • 分支管理
      • 问题管理
      • 里程碑管理
      • 发布管理
    • 持续集成
      • CircleCI
      • TravisCI
由 GitBook 提供支持
在本页
  • 测试
  • 接口测试
  • 覆盖率

这有帮助吗?

在Git上编辑
  1. 基础
  2. 测试与分析

单元测试

测试

在开发过程中,往往需要对某个方法或模块做功能测试和验证。在golang中内置了用于进行代码单元测试的包testing。

首先,对于需要测试的代码文件,在相同目录下创建一个同名带_test.go后缀的文件,比如代码文件a.go和单元测试文件a_test.go。在单元测试文件中,引入包testing,在下方定义以需要验证的方法名加Test前缀,形式参数为*testing.T的单元测试方法,比如需要测试方法B(),则对应的单元测试方法为TestB(*testing.T),*testing.T可以在测试过程中输出测试结果或者是报错中断测试。

例子:方法单元测试

a.go
package unittest

func Add(x, y int) int {
	return x + y
}

func Sub(x, y int) int {
	return x - y
}
a_test.go
package unittest

import (
	"testing"
)

func TestAdd(t *testing.T) {
	if Add(1, 2) != 3 {
		t.Error("error result of func A()")
	} else {
		t.Log("ok")
	}
}

func TestSub(t *testing.T) {
	if Sub(1, 2) != -1 {
		t.Error("error result of func Sub()")
	} else {
		t.Log("ok")
	}
}

运行命令go test -v执行单元测试,-v参数表示打印测试过程中输出的日志(查看更多的参数请使用go test -h)

测试结果输出如下:

=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
    a_test.go:11: ok
=== RUN   TestSub
--- PASS: TestSub (0.00s)
    a_test.go:19: ok
PASS
ok  	_/root/Projects/demo/unittest	0.003s

如果当前目录中有多个单元测试文件可以使用go test -v .指定执行当前目录下的所有测试文件。

单元测试文件需要遵循以下规则:

  • 文件名必须是_test.go结尾的,这样在执行go test的时候才会执行到相应的代码;

  • 必须导入 testing包;

  • 所有的测试用例函数必须是Test开头;

  • 测试用例会按照代码的书写顺序依次执行;

  • 测试函数TestXxx()的参数是testing.T,我们可以使用该类型来记录错误或者是测试状态;

  • 测试方法格式:func TestXxx (t *testing.T),Xxx部分可以为任意的字母数字的组合,但是首字母必须是大写;

  • 函数中通过调用testing.T的Error, Errorf, FailNow, Fatal, FatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。

接口测试

覆盖率

方法中往往带有许多的条件判断,在不同的测试条件下,测试的结果各不相同。为了保证测试代码的质量,需要尽可能多的覆盖测试方法中的各种条件,而代码的测试覆盖率可做为评估单元测试测试质量的一个依据。

在测试命令中附加参数-cover开启代码覆盖率统计

例子:代码覆盖率检查

创建目录$GOPATH/src/demo/coverage/,分别创建代码文件action.go和测试文件action_test.go

action.go
package coverage

import (
	"fmt"
)

func Action(kind string) {
	switch kind {
	case "cat":
		fmt.Println("喵")
	case "dog":
		fmt.Println("汪")
	case "frog":
		fmt.Println("呱")
	default:
		fmt.Println("I have no idea")
	}
}
action_test.go
package coverage_test

import (
	"demo/coverage"
	"testing"
)

func TestAction(t *testing.T) {
	coverage.Action("cat")
	coverage.Action("frog")
}

执行命令

go test -v -cover

测试结果

=== RUN   TestAction
喵
呱
--- PASS: TestAction (0.00s)
PASS
coverage: 60.0% of statements
ok  	demo/coverage	0.003s	coverage: 60.0% of statements

默认情况下只会检查_test.go文件中引用到的包,通过附加参数-coverpkg {包名1},{包名2},...可以指定需要检查覆盖率的包。

覆盖率检查可以生成可视化的测试报告,首先在测试的时候附加参数-coverprofile=coverage.data,将代码覆盖报告输出到coverage.data中,再通过命令go tool cover -html=coverage.data -o coverage.html根据覆盖报告生成一个html文件

执行命令

go test -v -cover -coverprofile=coverage.data
go tool cover -html=coverage.data -o coverage.html

通过浏览器打开生成的html文件即可查看代码覆盖情况

上一页测试与分析下一页性能测试

最后更新于4年前

这有帮助吗?

Testing Gin(httptest/assert)知乎专栏
Logo