github.com/stretchr/testify 包使用

在做一些通用组件代码时,测试用例覆盖是一个非常好的习惯

代码的测试覆盖,常用的到功能点为两个,一个是断言,一个是mock数据
mock数据我感觉这个包不大好用,还是只说断言吧

下面将以示例的方式对轮子包 testify 做一个说明

断言

一个简单的示例

这里不在对test基础使用做过多介绍,例如用例命名、文件名之类的,使用方法自行查阅资料

// test/run.go
package main

func Add(a, b int) int {
    return a + b
}

上面是一个业务代码,我们对Add方法做用例测试

使用标准库testing

// test/run_test.go
package test

import (
    "testing"
)

func TestAdd(t *testing.T) {
    got := Add(2, 2)
    want := 4
    if got != want {
        t.Errorf("Add(2,2) should be 4")
    }
}

运行这个用例 go test -run ^TestAdd$ limiter/test -v [-v 显示详细信息 ^$ 表示正则匹配只运行这个用例]

=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok      limiter/test    0.635s

其中的等于用例,需要自行通过if语句判断
接下来再看下第三方库github.com/stretchr/testify的使用

package test

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestAdd(t *testing.T) {
    assert.Equal(t, Add(2, 2), 4, "Add(2,2) should be 4")
}

再次运行

=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok      limiter/test    (cached)

同样的效果,使用assert库,代码也不是说多简洁,而是将用例有if语句判断,然后输出日志这种传统思维,转变成断言判断这种以结果为测试的思维导向
这种更倾向于测试结果化

常用的断言方法

最后一个参数大部分是断言的描述

- 等于
assert.Equal(t, Add(2, 2), 4, "Add(2,2) should be 4")
 
- 不等于
assert.NotEqual(t, 3, 5)
 
- true or false
assert.True(t, true, "should is true")
assert.False(t, false, "should is false")

- 是否是nil
assert.Nil(t, nil)
 
- contains 包含
assert.Contains(t, "hello world", "world") // 字符串
assert.Contains(t, [3]int{1, 2, 3}, 2) // 数组
assert.Contains(t, map[string]int{"a": 1, "b": 2}, "a") // map
assert.Contains(t, []string{"a", "b", "c"}, "b") // slice
 
- 是否是error
assert.Error(t, errors.New("a error"), errors.New("a error"))
assert.NoError(t, err) // err变量是否为nil
assert.ErrorIs(t, err, context.Canceled) // err变量是否是context.Canceled类型的err

- 是否是empty
assert.Empty(t, []string{})
assert.Empty(t, map[string]int{})
assert.Empty(t, "")
 
- zero 是否为零值
assert.Zero(t, 0) // 整数
assert.Zero(t, 0.0) // 小数
assert.Zero(t, false) // 布尔

一个语法糖,少传一个参数

func TestAssert(t *testing.T) {
    asserts := assert.New(t)
    asserts.Equal(2, 2)
    asserts.Equal(3, 3)

    // 下面这种写法,每次都要将testing.T传进去
    // assert.Equal(t, 2, 2)
    // assert.Equal(t, 3, 3)
}

require断言

assert.Zero(t, 0.1)

assert.Zero(t, false)

假如第一个断言失败,后面的断言不允许执行,require 就是来解决这个问题

assertrequire的区别

  • assert断言失败,测试函数继续执行;
  • require断言失败,测试函数直接退出;

assert支持的方法,require也都支持

package test

import (
    "fmt"
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestRequire(t *testing.T) {
    require.Equal(t, 2, 1)
    fmt.Println("==由于前面require失败,所以这里不会执行=====")
}

func TestAssert(t *testing.T) {
    assert.Equal(t, 2, 1)
    fmt.Println("===虽然前面assert会失败 但是仍会继续执行===")
}

通过上面代码,应该会有个清晰的认知了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容