51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 634|回复: 0
打印 上一主题 下一主题

[转贴] go单元测试工具testify简单介绍

[复制链接]
  • TA的每日心情
    无聊
    4 天前
  • 签到天数: 1050 天

    连续签到: 1 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-7-26 09:17:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    推荐一些在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套件就应运而生。


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-25 12:23 , Processed in 0.069072 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表