golang分层测试之单元测试-testing使用

前言

  • 基本上每一种高级计算机语言都有自己的代码逻辑测试的方式,也就是单元测试,其对于高级计算机语言的重要程度,大家在学习其他计算机语言的时候都有所了解,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编写测试代码的规范:
  1. 每个测试文件必须以 _test.go 结尾,并使用go test命令执行测试模块,否则golang无法识别出测试模块
  2. 作为测试模块文件,必须导入testing包
  3. 功能测试方法必须以 Test 开头,一般是接被测方法的名字,如TestAdd,但不强制
  4. 测试用例会按照源代码中写的顺序依次执行
  5. 测试方法TestXxx()的参数是testing.T,用于收集记录测试结果
  6. testing中的断言需要自己编写,通过在方法中通过调用testing.TError, 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方法,我们假设组合:
    1. 两个正数相加
    2. 两个负数相加
    3. 一正一负相加

示例代码

//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分层测试之单元测试-testing使用)