Go语言基础之单元测试 | 青训营笔记

85 阅读2分钟

文章第一句话为“这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

今天整理了Go语言中的单元测试的相关笔记。

测试函数

测试函数的格式

每个测试函数必须导入testing包,测试函数的基本格式(签名)如下:

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

测试函数的名字必须以Test开头,可选的后缀名必须以大写字母开头,举几个例子:

func TestAdd(t *testing.T){ ... }
func TestSum(t *testing.T){ ... }
func TestLog(t *testing.T){ ... }

其中参数t用于报告测试失败和附加的日志信息。 testing.T的拥有的方法如下:

func (c *T) Error(args ...interface{})
func (c *T) Errorf(format string, args ...interface{})
func (c *T) Fail()
func (c *T) FailNow()
func (c *T) Failed() bool
func (c *T) Fatal(args ...interface{})
func (c *T) Fatalf(format string, args ...interface{})
func (c *T) Log(args ...interface{})
func (c *T) Logf(format string, args ...interface{})
func (c *T) Name() string
func (t *T) Parallel()
func (t *T) Run(name string, f func(t *T)) bool
func (c *T) Skip(args ...interface{})
func (c *T) SkipNow()
func (c *T) Skipf(format string, args ...interface{})
func (c *T) Skipped() bool

测试函数示例

定义一个函数Split,它的功能是对字符串进行分割。

package split

import "strings"

// Split函数对字符串进行切割,例如:s = "a:b:c,sep = ":",切割得到的结果为:"abc"
func Split(s, sep string) (ret []string) {
	idx := strings.Index(s, sep)
	for idx > -1 {
		ret = append(ret, s[:idx])
		s = s[idx+len(sep):]
		idx = strings.Index(s, sep)
	}
	ret = append(ret, s)
	return ret
}

在当前目录下,创建一个split_test.go文件,并定义一个测试函数如下:

package split

import (
   "reflect"
   "testing"
)

func TestSplit(t *testing.T) {
   got := Split("我爱你", "爱")
   want := []string{"我", "你"}
   if !reflect.DeepEqual(want, got) {
      t.Errorf("want:%v got:%v\n", want, got)
   }
}

split包路径下,执行go test命令,可以看到输出结果如下:

split $ go test
PASS
ok      github.com/Q1mi/studygo/code_demo/test_demo/split       0.005s

测试组

将多个测试用例组合在一起

package split

import (
   "reflect"
   "testing"
)

func TestSplit(t *testing.T) {
   type test struct {
      input string
      sep   string
      want  []string
   }
   tests := map[string]test{
      "simple":      {input: "我爱你", sep: "爱", want: []string{"我", "你"}},
      "multi_test1": {input: "a:b:c:d", sep: ":", want: []string{"a", "b", "c", "d"}},
      "multi_test2": {input: "abcd", sep: "bc", want: []string{"a", "d"}},
   }
   for name, tc := range tests {
      got := Split(tc.input, tc.sep)
      if !reflect.DeepEqual(got, tc.want) {
         t.Errorf("name: %s failed want:%v got:%v\n", name, tc.want, got)
      }
   }
}

执行go test命令,测试通过

子测试

使用t.Run()执行子测试

package split

import (
   "reflect"
   "testing"
)

func TestSplit(t *testing.T) {
   type test struct {
      input string
      sep   string
      want  []string
   }
   tests := map[string]test{
      "simple":      {input: "我爱你", sep: "爱", want: []string{"我", "你"}},
      "multi_test1": {input: "a:b:c:d", sep: ":", want: []string{"a", "b", "c", "d"}},
      "multi_test2": {input: "abcd", sep: "bc", want: []string{"a", "d"}},
   }
   for name, tc := range tests {
      t.Run(name, func(t *testing.T) { // 使用t.Run()执行子测试
         got := Split(tc.input, tc.sep)
         if !reflect.DeepEqual(got, tc.want) {
            t.Errorf("expected:%#v, got:%#v", tc.want, got)
         }
      })
   }
}