golang 单元测试
单元测试是质量保证十分重要的一环,好的单元测试不仅能及时地发现问题,更能够方便地调试,提高生产效率。所以很多人认为写单元测试是需要额外的时间,会降低生产效率,是对单元测试最大的偏见和误解。
go 语言原生支持了单元测试,使用上非常简单,测试代码只需要放到以 _test.go 结尾的文件中即可。golang 的测试分为单元测试和性能测试,单元测试的测试用例以 Test 开头,性能测试以 Benchmark 开头。
举个例子
实现排列组合函数对应的单元测试和性能测试。
实现排列组合函数
// combination.go
package hmath
func combination(m, n int) int {
if n > m-n {
n = m - n
}
c := 1
for i := 0; i < n; i++ {
c *= m - i
c /= i + 1
}
return c
}
实现单元测试和性能测试
// combination_test.go
package hmath
import (
"math/rand"
"testing"
)
// 单元测试
// 测试全局函数,以TestFunction命名
// 测试类成员函数,以TestClass_Function命名
func TestCombination(t *testing.T) {
// 这里定义一个临时的结构体来存储测试case的参数以及期望的返回值
for _, unit := range []struct {
m int
n int
expected int
}{
{1, 0, 1},
{4, 1, 4},
{4, 2, 6},
{4, 3, 4},
{4, 4, 1},
{10, 1, 10},
{10, 3, 120},
{10, 7, 120},
} {
// 调用排列组合函数,与期望的结果比对,如果不一致输出错误
if actually := combination(unit.m, unit.n); actually != unit.expected {
t.Errorf("combination: [%v], actually: [%v]", unit, actually)
}
}
}
// 性能测试
func BenchmarkCombination(b *testing.B) {
// b.N会根据函数的运行时间取一个合适的值
for i := 0; i < b.N; i++ {
combination(i+1, rand.Intn(i+1))
}
}
// 并发性能测试
func BenchmarkCombinationParallel(b *testing.B) {
// 测试一个对象或者函数在多线程的场景下面是否安全
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
m := rand.Intn(100) + 1
n := rand.Intn(m)
combination(m, n)
}
})
}
运行测试
go test combination_test.go combination.go # 单元测试 go test --cover combination_test.go combination.go # 单元测试覆盖率 go test -bench=. combination_test.go combination.go # 性能测试
setup 和 teardown
setup 和 teardown 是在每个 case 执行前后都需要执行的操作,golang 没有直接的实现,可以通过下面这个方法实现全局的 setup 和 teardown,具体每个 case 的 setup 和 teardown 需要自己实现。
func TestMain(m *testing.M) {
// setup code...
os.Exit(m.Run())
// teardown code...
}
goconvey
这个第三方工具会自动帮我们跑测试,并且以非常友好的可视化界面帮我们展示测试的结果,包括测试失败的原因,测试覆盖率等等,内部还提供了很多友好的断言,能提高测试代码的可读性
使用方法
func TestMain(m *testing.M) {
// setup code...
os.Exit(m.Run())
// teardown code...
}
goconvey
这个第三方工具会自动帮我们跑测试,并且以非常友好的可视化界面帮我们展示测试的结果,包括测试失败的原因,测试覆盖率等等,内部还提供了很多友好的断言,能提高测试代码的可读性
使用方法
go get github.com/smartystreets/goconvey
然后用终端在测试代码的目录下运行 goconvey 命令即可
测试例子
package package_name
import (
"testing"
. "github.com/smartystreets/goconvey/convey"
)
func TestIntegerStuff(t *testing.T) {
Convey("Given some integer with a starting value", t, func() {
x := 1
Convey("When the integer is incremented", func() {
x++
Convey("The value should be greater by one", func() {
So(x, ShouldEqual, 2)
})
})
})
}
参考链接
go testing: http://docs.studygolang.com/pkg/testing/
goconvey: https://github.com/smartystreets/goconvey
goconvey 文档: https://github.com/smartystreets/goconvey/wiki/Documentation
goconvey 标准断言: https://github.com/smartystreets/goconvey/wiki/Assertions
thumb_up
转载|出处:http://t.cn/RnvsFRp
Golang技术交流群:426582602
golang 单元测试的更多相关文章
- ARTS-S golang单元测试
golang单元测试 在$GOPATH的src目录下建目录demo_unittest 在目录demo_unittest下建文件calc.go,内容如下: package demo_unittest f ...
- Golang单元测试框架整理
目录 一.单元测试是什么 二.单元测试的意义 三.Golang单元测试框架 3.1 Golang内置testing包 3.1.1 简单的测试 3.1.2 Benchmark 基准测试 3.1.3 运行 ...
- golang单元测试
使用testing进行单元测试 golang的测试库testing 测试文件与被测试文件在同一个包中 测试文件名为被测试文件名(去后缀)_test.go 测试用例函数以Test开头,TestFunc1 ...
- golang 单元测试&&性能测试
一:单元测试 1.为什么要做单元测试和性能测试 减少bug 快速定位bug 减少调试时间 提高代码质量 2.golang的单元测试 单元测试代码的go文件必须以_test.go结尾 单元测试的函数名必 ...
- golang 单元测试(一)
单元测试函数类型 Test(功能测试) 函数规则: 函数名: TestXxxx , 以Test为前缀.Xxxx以大写字母开头 参数类型: *testing.T func TestXxxx(t *tes ...
- golang单元测试简述
Golang中内置了对单元测试的支持,不需要像Java一样引入第三方Jar才能进行测试,下面将分别介绍Golang所支持的几种测试: 一.测试类型 Golang中单元测试有功能测试.基准测试. ...
- golang单元测试一(简单函数测试)
0.1.索引 https://blog.waterflow.link/articles/1663688140724 1.简介 单元测试是测试代码.组件和模块的单元函数.单元测试的目的是清除代码中的错误 ...
- 【GoLang】GoLang 单元测试、性能测试使用方法
单元测试代码: ackage test import ( // "fmt" "testing" ) func Test_FlowControl(t *testi ...
- Golang 单元测试和性能测试
开发程序其中很重要的一点是测试,我们如何保证代码的质量,如何保证每个函数是可运行,运行结果是正确的,又如何保证写出来的代码性能是好的,我们知道单元测试的重点在于发现程序设计或实现的逻辑错误,使问题及早 ...
随机推荐
- 数据结构——平衡二叉树(AVLTree)
3.平衡二叉树 平衡二叉树,又称AVL树,它是一种特殊的二叉排序树. 3.1 平衡二叉树的四种自旋 这个左旋.右旋,在方向上和我观念里的是相反的. 查了之后才知道: 1.外侧插入:LL.RR,都是在最 ...
- keras学习笔记2
1.keras的sequential模型需要知道输入数据的shape,因此,sequential的第一层需要接受一个关于输入数据shape的参数,后面的各个层则可以自动的推导出中间数据的shape,因 ...
- docker安装后启动不了 解决方法
第一种情况: 可能是你的selinux没有disabled,导致了守护docker的deamon进程启动不了 查看系统日志如果发现下列信息: May 7 12:34:14 localhost dock ...
- 通讯协议(二)HTTPS协议
摘要:本文尝试一步步还原HTTPS的设计过程,以理解为什么HTTPS最终会是这副模样.但是这并不代表HTTPS的真实设计过程.在阅读本文时,你可以尝试放下已有的对HTTPS的理解,这样更利于“还原”过 ...
- backtype.storm.generated.InvalidTopologyException:null问题的解决
程序启动报错:backtype.storm.generated.InvalidTopologyException:null 问题解决方法: 这个错误一般都是没有定义输出列造成的 检查Spout和Bol ...
- DataFrame 加减乘除
headlist = ['a', 'b'] datalist = [[1, 2], [0,3], [3,2]] df = pd.DataFrame(data=datalist,columns=head ...
- 多线程系列之 java多线程的个人理解(二)
前言:上一篇多线程系列之 java多线程的个人理解(一) 讲到了线程.进程.多线程的基本概念,以及多线程在java中的基本实现方式,本篇主要接着上一篇继续讲述多线程在实际项目中的应用以及遇到的诸多问题 ...
- ListView的优化问题
listview算是我们app中较为常用的控件之一了.而如何优化也是一个问题. listview的优化一般分为两类. 一布局优化. 对布局的优化是大家了解的. 1.复用convertview.andr ...
- ios软键盘将页面抵到上面后,关闭软键盘页面不回弹
这个问题有时候会导致弹出框确定按钮失效等一系列问题, 解决办法:失去焦点时将页面滚动到底层,或者最顶部,个人看实际情况滚动到适合位置 $('input,textarea').on('blur', fu ...
- CentOS7.6离线安装JDK1.8
卸载CentOS自带的openJDK: 查看openJDK命令:rpm -qa|grep java 结果: java-1.8.0-openjdk-headless-1.8.0.181-7.b13.el ...