前言
- 基本上每一种高级计算机语言都有自己的代码逻辑测试的方式,也就是单元测试,其对于高级计算机语言的重要程度,大家在学习其他计算机语言的时候都有所了解,golang的单元测试,自身提供的testing package能够满足基本的测试需求,当然还有丰富API的第三方开源库,比如 gocheck,golang单元测试会分几篇文章来讲解,这次主要讲一下 go 语言使用testing做单元测试的一些方法
testing框架使用
- Go语言通过内置库testing包提供自动化测试功能。包内测试只要运行命令 go test,就能自动运行符合规则的测试函数
示例代码
package hello import "testing" func TestHelloWorld(t *testing.T) { t.Log("hello world") }
- 说下golang编写测试代码的规范:
- 每个测试文件必须以 _test.go 结尾,并使用go test命令执行测试模块,否则golang无法识别出测试模块
- 作为测试模块文件,必须导入testing包
- 功能测试方法必须以 Test 开头,一般是接被测方法的名字,如TestAdd,但不强制
- 测试用例会按照源代码中写的顺序依次执行
-
测试方法TestXxx()的参数是
testing.T
,用于收集记录测试结果 -
testing中的断言需要自己编写,通过在方法中通过调用
testing.T
的Error
,Errorf
,FailNow
,Fatal
,FatalIf
方法来进识别测试通过与否,调用Log
方法用来记录测试的信息
命令行
- 单元测试使用 go test 命令启动
go test [-c] [-i] [build flags] [packages] [flags for test binary]
- 例如:
$ go test -v helloworld_test.go === RUN TestHelloWorld --- PASS: TestHelloWorld (0.00s) helloworld_test.go:8: hello world PASS ok command-line-arguments 0.004s
- 下面是go test的一些常用传参方式
go test //默认执行当前目录下以xxx_test.go的测试文件 go test -v //可以看到详细的输出信息。 go test -v xxx_test.go //指定测试单个文件,但是该文件中如果调用了其它文件中的模块会报错 go test -v xxx_test.go xxx.go //指定测试单个文件和被测文件 go test -v -test.run Testxxx //指定某个测试函数运行,注意点是函数会用Testxxx去匹配所有包含Testxxx字符串作方法名的方法 go test -v -cover //显示覆盖的声明程度
- 当然还有其他例如用来做压力测试的bench参数,这个在后续的文章中讲解
实战应用
-
废话少说,我们直接用demo代码来讲解
待测模块 demo.go
//demo by terrychow package main import "fmt" func Add(x,y int) int { return x+y } func main(){ z:=Add(1,2) fmt.Print(z) }
- 待测模块demo.go是一个简单的加法方式Add,这个也是本次测试的待测方法
- 由于待测模块demo.go为文件名,测试模块文件名必须以 _test 结尾,可命名为demo_test.go,不强制于被测文件前置同名,即可为other_test.go,测试模块文件路径可随意
测试模块 demo_test.go
//demo_test by terrychow package main import "testing" func TestAdd(t *testing.T) { s:=Add(1,2) if s!=3{ t.Error("Expected 3, got ", s) } }
- 依照测试代码规范,我们编写出测试代码模块,然后使用go test命令来执行
go test demo_test.go demo.go -v -cover
- 输出为
=== RUN TestAdd --- PASS: TestAdd (0.00s) PASS coverage: 33.3% of statements ok command-line-arguments 0.613s coverage: 33.3% of statements
- 调整一下代码断言值
//demo_test by terrychow package main import "testing" func TestAdd(t *testing.T) { s:=Add(1,2) if s!=4{//此处修改了错误的返回 t.Error("Expected 4, got ", s) } }
- 输出FAIL信息
=== RUN TestAdd --- FAIL: TestAdd (0.00s) demo_test.go:8: Expected 4, got 3 FAIL coverage: 33.3% of statements FAIL command-line-arguments 0.668s
- 一个基于golang内置的测试框testing的单元测试已经实现了
进阶玩法
-
有时候我们针对一个方法的测试,会结合如路径覆盖、条件覆盖和语句覆盖等测试思路来进行对测试数据的组合测试,利用不同的数据组合验证覆盖方式,于是就有了组合测试的方式,针对Add方法,我们假设组合:
- 两个正数相加
- 两个负数相加
- 一正一负相加
示例代码
//demo by terrychow package main import "testing" func TestGroupAdd(t *testing.T){ var testdata=[] struct{ arg1 int arg2 int sum int }{ {1,1,2}, {-1,-1,-2}, {-1,1,0}, } for _, test:=range testdata{ sum:=Add(test.arg1,test.arg2) if sum!=test.sum{ t.Errorf("arg1 %v and arg2 %v not except sum %v",test.arg1,test.arg2,test.sum) } } }
- 输出结果为
=== RUN TestGroupAdd --- PASS: TestGroupAdd (0.00s) PASS coverage: 33.3% of statements ok command-line-arguments 0.583s coverage: 33.3% of statements
- 假设其中一个为错误的数据,如
package main import "testing" func TestGroupAdd(t *testing.T){ var testdata=[] struct{ arg1 int arg2 int sum int }{ {1,1,2}, {-1,-1,-1},//此处的sum为错误值 {-1,1,0}, } for _, test:=range testdata{ sum:=Add(test.arg1,test.arg2) if sum!=test.sum{ t.Errorf("arg1 %v and arg2 %v not except sum %v",test.arg1,test.arg2,test.sum) } } }
- 输出FAIL信息
=== RUN TestGroupAdd --- FAIL: TestGroupAdd (0.00s) demo1_test.go:17: arg1 -1 and arg2 -1 not except sum -1 FAIL coverage: 33.3% of statements FAIL command-line-arguments 0.688s
- 会有对应的错误信息返回,说明错在哪一行
小结
- testing作为go语言内置的测试库,其当然还不仅仅是做单元测试,之后讲解的API和UI自动化测试,以及后面的压力、性能测试也会使用到testing,足见其核心作用
- 但testing也是有其限制性,没有良好的测试断言以及测试报告,靠使用者不断地写if else来判断显然麻烦,这也是下一篇文章要讲解go最常用单元测试框架gocheck,下回内容更精彩,请继续关注后续更新,谢谢大家
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- golang分层测试之单元测试-gocheck使用
- golang分层测试之http接口测试入门
- golang分层测试之httpexpect+httptest测试应用
- golang分层测试之语言入门
- 说说分层测试中HTTP的API测试工具
- DDD 分层
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
SHA 加密
SHA 加密工具
RGB HSV 转换
RGB HSV 互转工具