这是我参与「第五届青训营」伴学笔记创作活动的第 6 天
前言
测试是软件开发必不可少的环节,本文介绍go语言的测试技术,主要包括单元测试、mock测试和基准测试三部分。
单元测试
单元测试指对软件应用程序的单元或单个组件进行测试,目的是验证单元组件的功能可用性。go语言的单元测试借助go test命令进行。
基本规范
- 测试的源文件以
_test.go为后缀名,在执行go build时不会被构建成包的一部分。 - 测试函数需要导入testing包。
- 测试函数以
Test为函数名前缀。 - 初始化逻辑放在
TestMain中。
go test
go test:在没有参数指定包的情况下默认采用当前目录对应的包。
go test -v :打印每个测试函数的名字和运行时间。
go test -run:对应一个正则表达式,只有测试函数名被它正确匹配的测试函数才会被go test测试命令运行。
测试覆盖率
go test -coverprofile=c.out:使用-coverprofile标志参数使测试代码中插入生成钩子来统计覆盖率数据。在运行每个测试前,系统将待测代码拷贝一份并做修改,在每个词法块都会设置一个布尔标志变量。当被修改后的被测试代码运行退出时,将统计日志数据写入c.out文件,并打印一部分执行的语句的一个总结。
go test -cover:类似于-coverprofile,但生成的是摘要。
go tool cover -html=c.out:运行测试覆盖率工具,打印测试日志并生成HTML报告。
Mock测试
在一些复杂项目中,会依赖一些数据库、文件或缓存等,这些属于项目的一个强依赖,如果单元测试中直接调用数据库等外部依赖,那测试是不稳定的,因此需要引入mock机制。
go mock
gomock是官方提供的mock框架,同时还提供了mockgen工具来辅助生成测试代码。
- 安装
$ go get -u github.com/golang/mock/gomock
$ go install github.com/golang/mock/mockgen
- 用法
source:从源文件生成mock接口(通过 -source 启用)
mockgen -source=foo.go [other options]
reflect:通过使用反射程序来生成mock接口。它通过传递两个非标志参数来启用——导入路径和逗号分隔的接口列表。
mockgen database/sql/driver Conn,Driver
monkey
常用的开源mock包:github.com/bouk/monkey
提供了快速mock函数:
- 为一个函数打桩
- 为一个方法打桩
打桩:可以理解为用一个函数A去替换一个函数B,B就是原函数,A就是打桩函数。
基准测试
基准测试是测量一个程序在固定工作负载下的性能。在Go语言中,基准测试函数和普通测试函数写法类似,但是以Benchmark为前缀名,并且带有一个*testing.B类型的参数。
*testing.B参数除了提供和*testing.T类似的方法,还有额外一些和性能测量相关的方法。它还提供了一个整数N,用于指定操作执行的循环次数。
课后个人总结
- golang提供了简单而强大的测试工具,通过对文件名和函数名的约束可以轻易地实现单元测试和基准测试。
- 在需要使用到外部依赖的情况下,可以利用mock测试来模拟外部依赖,避免发生不必要的错误。常用的mock测试框架包括go mock 和 monkey等。