51Testing软件测试论坛

标题: go单元测试工具testify简单介绍 [打印本页]

作者: lsekfe    时间: 2022-7-26 09:17
标题: go单元测试工具testify简单介绍
推荐一些在go里面的测试工具。其中最著名的testify就是不得不推荐的了。很多开源项目都在用这个库构建测试用例。说到这里突然想到之前有人给goleveldb提交pr代码写自己的单元测试时引入了这个库,我还“批斗”了他,说修改代码和引入新的库是两码事,请你分开做hhhh,现在想想还蛮不好意思的。回归正题,我们来简单介绍一些testify这个库。
  testify
  testify这个库主要有三个核心内容,assert, mock, suite。assert就是断言,可以封装了一些判断是否相等,是否会有异常之类的。文章篇幅有限,这里就不对assert的api一一介绍了,感兴趣的朋友们可以看衍生阅读的相关文章。这里我主要介绍mock和suite模块。
  mock
  在我们要准备测试的时候经常需要准备一些数据,mock模块通过实现接口的方式来伪造数据。从而在测试的时候可以用这个mock的对象作为参数进行传递。废话不多说我们看下怎么简单的实践一下。
  首先我们定义一个接口:
  1.  //go:generate mockery --name=Man
  2.   type Man interface {
  3.     GetName() string
  4.     IsHandSomeBoy() bool
  5.   }
复制代码
这个接口定义了一个男孩子,一个方法是获取他的名字,第二个方法是看他是不是帅哥。这里我还推荐使用go:generate的方式执行mockery(执行go get -u -v github.com/vektra/mockery/.../安装)命令去生成对应的mock对象(生成的代码会放在当前目录的mocks目录下,当然你也可以在命令上添加参数指定生成路径),这样就不需要我们去实现mock对象的一些方法了。下面我们看下生成的代码是怎么样的。

  1.  // Code generated by mockery v2.10.0. DO NOT EDIT.
  2.   package mocks
  3.   import mock "github.com/stretchr/testify/mock"
  4.   // Man is an autogenerated mock type for the Man type
  5.   type Man struct {
  6.     mock.Mock
  7.   }
  8.   // GetName provides a mock function with given fields:
  9.   func (_m *Man) GetName() string {
  10.     ret := _m.Called()
  11.     var r0 string
  12.     if rf, ok := ret.Get(0).(func() string); ok {
  13.       r0 = rf()
  14.     } else {
  15.       r0 = ret.Get(0).(string)
  16.     }
  17.     return r0
  18.   }
  19.   // IsHandSomeBoy provides a mock function with given fields:
  20.   func (_m *Man) IsHandSomeBoy() bool {
  21.     ret := _m.Called()
  22.     var r0 bool
  23.     if rf, ok := ret.Get(0).(func() bool); ok {
  24.       r0 = rf()
  25.     } else {
  26.       r0 = ret.Get(0).(bool)
  27.     }
  28.     return r0
  29.   }
复制代码
那么我们怎么使用呢?看看下面代码:

  1. func TestMan_All(t *testing.T) {
  2.   man := mocks.Man{}
  3.     // 可以通过这段话来添加某个方法对应的返回
  4.   man.On("GetName").Return("Elliot").On("IsHandSomeBoy").Return(true)
  5.   assert.Equal(t, "Elliot", man.GetName())
  6.   assert.Equal(t, true, man.IsHandSomeBoy())
  7.   }
复制代码
suite
  有时候我们可能需要测的不是一个单独的函数,是一个对象的很多方法,比如想对leveldb的一些主要方法进行测试,比如简单的读写,范围查询,那么如果每个功能的单元测试都写成一个函数,那么可能这里会重复初始化一些东西,比如db。其实这里是可以做到共享一些状态的,比如数据写入之后就可以测试把这个数据读出来,或者范围查询。在这里的话其实用一种比较紧密的方式把他们串联起来会比较好。那么suite套件就应运而生。







欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2