golang 单元测试

  • 文件格式:go单元测试,有固定的名称格式,所有以_test.go为后缀名的源文件在执行go build 时不会被构建成包的一部分,他们是go test 测试的一部分。

    测试函数

  • 函数格式:每个测试函数是以Test为函数名称前缀。
    每个测试函数必须导入testing包。

  1. func TestName(t *testing.T) {
  2. // ...
  3. }

基准测试(benchmark)

  • 函数格式:函数前缀名称Benchmark。
  • 作用:用于衡量函数的性能。会多次运行基准函数,计算一个平均的执行时间。

    示例函数

  • 函数前缀名称Example

  • 作用:提供一个由编译器保证正确性的示例文档。

    命令介绍

  1. 参数-v可用于打印每个测试函数的名字和运行时间:
  1. go test -v

2.-run 测试制定的函数名称

  1. go test -v -run="函数名称"

3.-cover 查看测试覆盖率

  1. go test -v -run="" -cover
  2. go test -cover /model/test/list

4.最后统统执行一遍全部测试用例

  1. go test

5.示例

  1. go test -run '' # Run all tests.
  2. go test -run Foo # Run top-level tests matching "Foo", such as "TestFooBar".
  3. go test -run Foo/A= # For top-level tests matching "Foo", run subtests matching "A=".
  4. go test -run /A=1 # For all top-level tests, run subtests matching "A=1".


表格驱动测试(自动生成)

开源:gotests开源地址

安装gotests

  1. 执行下面命令
  1. go get -u github.com/cweill/gotests

2.将下载的gotests目录,配置到PATH环境变量中

  1. export PATH=$PATH:$GOBIN:$GOPATH:$MYSQLBIN

gotests使用

  1. -all
  2. generate tests for all functions and methods
  3. 为所有函数和方法生成go测试
  4. -excl string
  5. 为没有匹配的函数和方法生成go测试
  6. regexp. generate tests for functions and methods that don't match. Takes precedence over -only, -exported, and -all
  7. -exported
  8. 为导出的函数和方法生成go测试。
  9. generate tests for exported functions and methods. Takes precedence over -only and -all
  10. -i
  11. 在错误消息中打印测试输入
  12. print test inputs in error messages
  13. -nosubtests
  14. 禁用子测试生成。仅适用于Go 1.7+
  15. disable generating tests using the Go 1.7 subtests feature
  16. -only string
  17. 正则表达式。生成仅匹配的函数和方法的测试。优先于-all
  18. regexp. generate tests for functions and methods that match only. Takes precedence over -all
  19. -template_dir string
  20. 可选的。包含自定义测试代码模板的目录的路径
  21. optional. Path to a directory containing custom test code templates
  22. -w
  23. 将输出写入(测试)文件而不是stdout
  24. write output to (test) files instead of stdout

常用操作

1.进入对应的要被生成单元测试的目录
2.在该目录下执行命令
3.生成指定函数的单元测试,输出到命令行,然后复制粘贴到目标处。

  1. gotests -only "函数名称" 文件名称.go

4.生成全部测试函数

  1. gotests -all 文件名称.go
  2. gotests -only " 方法名称" 文件名称
  3. gotests -all -w origin.go, origin_test.go

会自动创建在当前目录下,并自动生成测试代码,只需要将不同的测试数据按照tests定义的结构写在//TODO:Add test cases下面,测试用例就完成了。



mock测试

参考文章
mock是单元测试中常用的一种测试手法,mock对象被定义,并能够替换掉真实的对象被测试的函数所调用。
而mock对象可以被开发人员很灵活的指定传入参数,调用次数,返回值和执行动作,来满足测试的各种情景假设。

使用场景

  • 依赖的服务返回不确定的结果,如获取当前时间。
  • 依赖的服务返回状态中有的难以重建或复现,比如模拟网络错误。
  • 依赖的服务搭建环境代价高,速度慢,需要一定的成本,比如数据库,web服务
  • 依赖的服务行为多变。
    为了保证测试的轻量以及开发人员对测试数据的掌控,采用mock来斩断被测试代码中的依赖不失为一种好方法。

每种编程语言根据语言特点其所采用的mock实现有所不同。

mockery

mockery

安装

go get github.com/vektra/mockery/…/

使用

Run: mockery -name=Stringer生成的mock名称 and the following will be output to mocks/Stringer.go
1、生成mock文件,默认在./mocks目录下

  1. mockery -name=Mocker接口名

2、生成mock输出到控制台

  1. mockery -name=接口名 -print

代码处理:

1.业务接口

  • 1.定义被mock的接口
  • 2.定义类(实现接口)
  • 3.定义个方法New(),返回该类对象
  1. // 1.定义接口
  2. type Driver interface {
  3. Add(*ImportSet) (int64, error)
  4. }
  5. // 2.定义类,实现该接口
  6. type driverImp struct{}
  7. //3.定义方法,创建该类对象
  8. func NewDriver() Driver {
  9. return &driverImp{}
  10. }

2.生成mock方法

mockery -name=接口名 -print
生成要被mock的方法

3.service层调用处

  1. // 用创建对象的方法,获取对象,调用接口方法
  2. NewDriver().QueryImportDetails(req.ImportUuid)

4.单元测试

  1. func TestFunc(t *testing.T) {
  2. //保存原来的对象helper.ListDrv就是newDrv()
  3. oldFd := helper.ListDrv
  4. //最后还原对象
  5. defer func() {
  6. helper.ListDrv = oldFd
  7. }()
  8. type args struct {
  9. ctx context.Context
  10. req
  11. }
  12. tests := []struct {
  13. name string
  14. args args
  15. want *****
  16. wantErr bool
  17. //在表驱动中,写mock方法
  18. mock func()
  19. }{
  20. {
  21. name: "error",
  22. args: args{
  23. ctx: context.Background(),
  24. req: **,
  25. },
  26. wantErr: false,
  27. want: ***
  28. mock: func() {
  29. mfd := &listmock.Driver{}
  30. mfd.On("QueryCount").Return(int64(0), nil)
  31. mfd.On("QueryList", mock.Anything, mock.Anything).Return([]list.ImportList{{UUID: "xxx", Description: "ddddd"}}, nil)
  32. //还原对象
  33. helper.ListDrv = mfd
  34. },
  35. },
  36. },
  37. // 测试用例
  38. for _, tt := range tests {
  39. // 执行mock方法
  40. tt.mock()
  41. t.Run(tt.name, func(t *testing.T) {
  42. 里面的单元测试内容不变
  43. }



常用命令

-v是显示出详细的测试结果,
-cover 显示出执行的测试用例的测试覆盖率
1 测试单个文件,一定要带上被测试的原文件

  1. go test -v -cover file1_test.go file.go

2 测试单个函数方法

  1. go test -v -cover -run TestFuncName

3 测试整个api包
在包统计目录下

  1. go test -v -cover ./api/...

4、自动生成测试用例,为指定的函数生成单元测试,输出到控制台

  1. gotests -only "函数名称" file(源文件名称).go

5、自动生成测试用例,为指定文件生成单元测试,输出到文件中

  1. gotests -all -w origin.go, origin_test.go

6、生成mock

  1. //输出到控制台
  2. mockery -name=接口名 -print
  3. //输出到./mocks/接口名.go文件中
  4. mockery -name=接口名


7人点赞

Golang

作者:空白白的
链接:https://www.jianshu.com/p/fa3f7c7d29cd
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。