马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
Golang相干测试框架
在 Go 语言里,最常用的测试框架有:自带的 testing 包、GoConvey 和 testify。
1、Go自带的testing包
testing 包是官方内置的,无需额外安装,也是大多数项目标首选。
(1)单元测试
- 测试文件必须以 _test.go 末了,比方:calc_test.go
- 测试函数必须以 Test 开头(保举写成 Test+函数名,更直观)
- 测试函数署名固定:func TestXxx(t *testing.T),不能有返回值
- 测试函数内部用 t.Errorf / t.Fatal 等方法输堕落误
- t.Errorf:标记测试失败,但 继承实验背面的测试代码。
- t.Fatal:标记测试失败,并 立即停止当前测试函数。
- # 执行当前目录下所有 *_test.go 文件
- go test -v
- # 只执行指定文件中的测试
- go test -v calc_test.go calc.go
- # 执行指定的测试函数(-count=1 表示禁用缓存,强制重新运行)
- go test -v -run TestAdd calc_test.go calc.go -count=1
复制代码 更详细的参数请参考:Go test下令行参数 (2)性能测试
- 文件定名:和单测一样,文件必须以 _test.go 末了,如许 go test 才华辨认。
- 函数定名:基准测试函数要以 Benchmark 开头,且必须是导出函数,比如 BenchmarkAdd。
- 函数署名:基准测试函数必须吸收一个 *testing.B 范例的参数,不能有返回值。
- 重置计时器:b.ResetTimer() 用来清空前面初始化代码的耗时,包管只统计真正的测试部分。
- 循环实验:基准测试里要用 for i := 0; i < b.N; i++ { ... },被测的代码放在循环里。
- b.N 的作用:Go 框架会自动调解 b.N,让测试至少运行 1 秒左右,如许结果更稳固。终极输出的是匀称每次运行的耗时(比如 0.25 ns/op 表现每次 0.25 纳秒)。
在calc文件夹的calc_test.go文件中新增BenchmarkAbs和BenchmarkAdd方法。
基准测试的目标就是 尽大概正确地衡量一段代码的性能,包罗运行时间、内存分配等。
- 焦点思绪:同一段代码运行很多次(b.N 次),用「总耗时 ÷ b.N」算出匀称每次实验的耗时。
- b.N 的作用:b.N 由 Go 测试框架自动决定,会动态调解,包管测试至少运行 1 秒左右,制止样本太少导致结果禁绝。
- 运行过程:当实验 go test -bench=. 时,框架会先用很小的 b.N(比如 1、2、5、19)试跑频频,估算耗时,再渐渐增大 b.N,直到结果稳固。
- 输出示例:比如陈诉里写 1000000000 0.25 ns/op,意思是运行了 10 亿次,每次匀称耗时 0.25 纳秒。
- # 运行所有基准测试
- go test -bench=.
- # 运行所有基准测试并显示内存分配情况
- go test -bench=. -benchmem
- # 只运行基准测试,不运行单元测试
- go test -run=none -bench=.
- # 指定测试时间
- go test -bench=. -benchtime=3s
- # 指定运行轮数
- go test -bench=. -count=3
- # 组合使用多种参数
- go test -run=none -bench=. -benchmem -benchtime=3s -count=3
复制代码 2、GoConvey
https://github.com/smartystreets/goconvey GoConvey 是一款专门为 Golang 打造的测试框架,它不但能帮你更方便地构造和运行单元测试,还自带了丰富的断言方法,让测试代码更简便直观。更酷的是,它还支持 Web 界面:只要在项目里写好测试,用 go test 下令就能照常运行;如果你想要更直观的体验,可以直接运行 goconvey,然后在欣赏器里访问 http://localhost:8080,就能看到实时的测试结果展示。 相比起纯粹使用标准库的 testing 包,Convey 让单元测试的誊写和阅读都更流畅,尤其得当必要频仍跑测试、调试逻辑的开发过程。
(1)安装依赖:go get github.com/smartystreets/goconvey
(2)demo
3、testify
Testify 是 Go 语言生态里非常常用的一个 断言风格测试框架。它不但提供了开发者最常用的断言方法(让测试代码更简便、可读性更强),还额外封装了三个焦点功能模块:
- Assertions(断言):内置了丰富的断言方法,制止重复编写样板式判断逻辑。
- Suite(测试套件):支持将一组相干测试构造在一起,方便共享初始化、清算等逻辑。
- Mock(模拟):提供强大的 Mock 本领,方便在单元测试中模拟依赖对象或外部接口。
借助 Testify,我们可以用更靠近自然语言的方式编写测试,不但进步开发服从,也让测试结果更易于明确。
官方文档:https://godoc.org/github.com/stretchr/testify (1)依赖安装:go get -u -v github.com/stretchr/testify
(2)测试用例
① assert包提供了断言工具,在实验时会将case标记为失败,但步调不会退出,而是继承往下实验。- package testify
- import (
- "testing"
- "github.com/stretchr/testify/assert"
- )
- func Test_assert(t *testing.T) {
- a := 2
- b := 3
- // 第一个断言失败(故意写错期望值)
- assert.Equal(t, 6, a+b, "第一个断言:2+3应该等于5,不是6")
- // 程序继续执行下面的断言
- t.Log("这行代码被执行了,说明程序没有中断")
- // 第二个断言通过
- assert.Equal(t, 5, a+b, "第二个断言:2+3应该等于5")
- // 第三个断言也会执行
- assert.True(t, a < b, "第三个断言:2应该小于3")
- t.Log("所有断言都已执行完毕")
- }
复制代码
② require包提供与asser包雷同的全局函数,与assert差别的是,require会制止当前测试。- package testify
- import (
- "testing"
- "github.com/stretchr/testify/require"
- )
- func Test_require(t *testing.T) {
- name := "Tom"
- age := 18
- // 这个会失败并停止测试
- require.Equal(t, "dazuo", name, "测试会在这里停止")
- require.Equal(t, 18, age, "测试会在这里停止")
- // 这行不会被执行
- t.Log("这行代码不会被执行")
- }
复制代码
③ mock包提供了一种轻松编写模拟对象的机制,可以在编写测试代码时替换实际对象使用模拟对象。- func Test_mock(t *testing.T) {
- // 创建模拟对象
- mockS := &mockStorage{}
- // 设置对Store方法期望的调用,参数必须匹配;返回该方法调用时的返回值
- mockS.On("Store", "name", "Tom").Return(1, nil).Once()
- result, err := mockS.Store("name", "Tom")
- assert.NoError(t, err)
- assert.Equal(t, 1, result)
- mockS.AssertExpectations(t) // 断言所有预期的调用都发生了
- }
复制代码
若该方法没有被调用:- func Test_mock(t *testing.T) {
- // 创建模拟对象
- mockS := &mockStorage{}
- // 设置对Store方法期望的调用,参数必须匹配;返回该方法调用时的返回值
- mockS.On("Store", "name", "Tom").Return(1, nil).Once()
- mockS.AssertExpectations(t) // 断言所有预期的调用都发生了
- }
复制代码
|