今天这篇内容是对测试内容的补充,目录如下:
表格测试是一种编写更清晰的测试函数的方法;
顾名思义,表格驱动测试,就是指通过表格列举的方式来实现测试用例,表格中包含输入和预期输出,以及其他信息;这种方式是我们对测试的逻辑和思路更加清晰;
官方表格驱动测试的案例:
// fmt包中有如下一段测试代码: // 定义测试的表格,包含了in输入字段和out期待输出字段 // 并且定义了该表格中的测试用例 // 然后使用t.Run的方式对每个用例进行测试 var flagtests = []struct { in string out string }{ {"%a", "[%a]"}, {"%-a", "[%-a]"}, {"%+a", "[%+a]"}, {"%#a", "[%#a]"}, {"% a", "[% a]"}, {"%0a", "[%0a]"}, {"%1.2a", "[%1.2a]"}, {"%-1.2a", "[%-1.2a]"}, {"%+1.2a", "[%+1.2a]"}, {"%-+1.2a", "[%+-1.2a]"}, {"%-+1.2abc", "[%+-1.2a]bc"}, {"%-1.2abc", "[%-1.2a]bc"}, } func TestFlagParser(t *testing.T) { var flagprinter flagPrinter for _, tt := range flagtests { t.Run(tt.in, func(t *testing.T) { s := Sprintf(tt.in, &flagprinter) if s != tt.out { t.Errorf("got %q, want %q", s, tt.out) } }) } }
如果测试用例我们例举了非常多的话,我们希望测试用例可以并行执行,本身每个测试用例之间就是互不干扰的,因此上述代码可如下优化:
func TestFlagParser(t *testing.T) { var flagprinter flagPrinter for _, tt := range flagtests { ft := tt // 1. 重新声明变量,避免多个goroutine中使用了相同的变量 t.Run(ft.in, func(t *testing.T) { t.Parallel() // 2. 使用t.Parallel表示每个子测试之间能够彼此并行运行 s := Sprintf(ft.in, &flagprinter) if s != ft.out { t.Errorf("got %q, want %q", s, ft.out) } }) } }
如上,既是表格驱动测试
的用法;先定义表格以及测试用例,然后再通过t.Run
子测试方式遍历表格;
gotests
gotests
是一种自动生成表格驱动测试代码的工具;
使用案例:
比如在此前的[一文搞定golang单元测试]中,我们创建了split.go
的业务文件;
安装gotests
工具:$ go get -u github.com/cweill/gotests/...
执行命令:gotests -all -w split.go
;关于gotests
的命令参数,大家可以去官网学习一下;
-all
:生成所有的测试函数和方法-w
:输出测试结果到文件而不是控制台生成的测试代码的格式如下,我们需要在todo的位置添加我们的测试逻辑即可:
package base_demo import ( "reflect" "testing" ) func TestSplit(t *testing.T) { type args struct { s string sep string } tests := []struct { name string args args wantResult []string }{ // TODO: Add test cases. } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if gotResult := Split(tt.args.s, tt.args.sep); !reflect.DeepEqual(gotResult, tt.wantResult) { t.Errorf("Split() = %v, want %v", gotResult, tt.wantResult) } }) } }
安装go get github.com/stretchr/testify
;提供了更优雅的,灵活的,可mock的等等工具;
常用:testify/assert
或testify/require
或testfy/mock
示例:
单元测试的时候,经常需要用到断言来检验测试结果,但是golang官方没有提供断言语法,导致我们可能会使用大量的ifelse语句;
testfy/assert
为我们提供了很多常用的断言函数,让我们的测试代码实现的更加优雅;
比如在此前的[一文搞定golang单元测试]中我们检验TestSplit
结果的方式如下:
if !reflect.DeepEqual(want, got) { t.Errorf("expected:%v, got:%v", want, got) }
如果我们使用 testfy/assert
的话,就可以如下简化:
// t是testing.T assert.Equal(t, want, got) // 使用assert提供的断言函数; //或者如下使用方式,先创建assert对象: assert := assert.New(t) assert.Equal(123, 123, "they should be equal")//是否相等测试 assert.NotEqual(123, 456, "they should not be equal")//是否不等测试 assert.Nil(object)//是否nil测试 if assert.NotNil(object) { assert.Equal("Something", object.Value) }
testfy
中除了assert工具以外,还有常用的是testfy/require
工具,以及还提供了mock
和http
的工具,大家可以去官网了解一下;
什么是mock呢?比如我们的测试中有一个步骤是向用户成功发送邮件,事实上我们需要用户确认邮件后,才认为该邮件用户已确认;但实际测试中,我们不可能真的给用户发送邮件,或者说我们不可能每次测试都真的发送邮件(假如不是邮件而是短信的话,每次测试可都是需要花钱的),因此mock就可以模拟用户确认短信的行为,即模拟功能;
mock技术可用于各种不同的系统,例如模拟数据库查询或者是与其他API的交互等等,非常实用;
坚持每日输出go开发+面试题+算法+工作经验等后端相关技术
更多博客内容请查看bigshake