linuxea:go基准测试和单元测试(36)


一般而言,我们通过包中的函数调用来做一些测试,比如正常的调用代码,如果错误然后追寻代码位置和行数来判断,如下:

I. 7.单元测试

  • 示例

假设现在创建一个目录codetest,而后放一段代码,如,add函数,做一个加法运算,如下

[root@linuxea.com /opt/Golang/inTest]# cat codetest/calc.go 
package codetest

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

而后在main函数中调用

[root@linuxea.com /opt/Golang/inTest]# cat main.go 
package main
import (
    "testmod/info"
    "testmod/codetest"
    "fmt"
)
func main(){
    fmt.Println(info.Name)
    
    a := codetest.Add(1,2)
    fmt.Println(a)

}

运行

[root@linuxea.com /opt/Golang/inTest]# go run main.go 
mark
3

但是这种方式并不可靠。我们可以使用go的单元测试。

当我们对代码进行重新修改后,我们有必要对一些模块进行单元测试以确保代码运行正常。我们做一个简单的示例。测试上面Add的函数

7.1单元测试

还是如上所示,我们仍然测试ADD函数,加入go的测试风格。测试函数需要导入testing包,我们在calc的目录下创建一个go文件,文件中函数名称都是以Test开头,传入一个参数t,是*testing.T指针类型,在测试函数中调用函数进行返回值测试,当测试失败可通过testing.T结构体的Error*函数抛出错误

func TestAdd(t *testing.T){}

而后直接调用Add函数,如下:

func TestAdd(t *testing.T){
    if 4 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

如上所示,调用Add(1,2)的结果如果不等于4,就抛出错误

代码块

[root@linuxea.com /opt/Golang/inTest/codetest]# cat calc_test.go 
package codetest

import "testing"

func TestAdd(t *testing.T){
    if 4 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

而后我们运行test testmod/codetest

test testmod/codetest中的testmod是modules中init时候的名字,codetest是当前目录下的包名

[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest
--- FAIL: TestAdd (0.00s)
    calc_test.go:7: 1加2不等于3
FAIL
FAIL    testmod/codetest    0.003s

我们修改成正确的看看。

把条件判断改成3。很明显,1+2,是等于3的

package codetest

import "testing"

func TestAdd(t *testing.T){
    if 3 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

运行

[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest
ok      testmod/codetest    (cached)

7.2测试覆盖率

  • -coverprofile

我们在添加一个函数在calc.go

# cat calc.go 
package codetest

func Add(x,y int) int {
    if x >  0{
        return x + y
    }else {
        return x
    }
}
func Multi(x,y int) int {
    return x * y 
}

测试文件calc_test.go

package codetest

import "testing"

func TestAdd(t *testing.T){
    if 3 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

运行

[root@linuxea.com /opt/Golang/inTest/codetest]# go test testmod/codetest -coverprofile=calc.out
ok      testmod/codetest    0.002s  coverage: 50.0% of statements

这时候会产生一个calc.out

文件列表:

[root@linuxea.com /opt/Golang/inTest/codetest]# ll
total 12
-rw-r--r-- 1 root root 137 Oct  2 10:04 calc.go
-rw-r--r-- 1 root root 164 Oct  2 10:04 calc.out
-rw-r--r-- 1 root root 119 Oct  2 10:04 calc_test.go

7.3查看cover文件

使用tool cover -html calc.out

[root@linuxea.com /opt/Golang/inTest/codetest]# go tool cover -html calc.out 
HTML output written to /tmp/cover001206950/coverage.html

这时候生成了一个html的文件存放在/tmp/cover001206950/coverage.html

红色是未覆盖的测试

7.4多条件测试覆盖率

上述中,只覆盖率判断了x大于0的代码,在覆盖测试else这块,如下:

func TestAdd2(t *testing.T){
    if -1 != Add(-1,3){
        t.Errorf("-1")
    }
}

代码块

package codetest

import "testing"

func TestAdd(t *testing.T){
    if 3 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

func TestAdd2(t *testing.T){
    if -1 != Add(-1,3){
        t.Errorf("-1")
    }
}

运行

[root@linuxea.com /opt/Golang/inTest/codetest]#  go test testmod/codetest -coverprofile=calc.out
ok      testmod/codetest    0.002s  coverage: 75.0% of statements

转换html文件

[root@linuxea.com /opt/Golang/inTest/codetest]# go tool cover -html calc.out 
HTML output written to /tmp/cover693930635/coverage.html

如下:

两个if分支都被测试到,所以变成了绿色。

II. 8.基准测试

基准测试通常用来测试性能,函数使用Beanchmark开头,参数也是*testing.B

  • 示例

创建一个函数名称为Fact的阶层函数

func Fact(n int) int {
    if n == 0 {
        return 1
    }
    return n * Fact(n-1)
}

代码块

package codetest

func Add(x,y int) int {
    if x >  0{
        return x + y
    }else {
        return x
    }
}
func Multi(x,y int) int {
    return x * y 
}

func Fact(n int) int {
    if n == 0 {
        return 1
    }
    return n * Fact(n-1)
}

calc_test.go中基准测试写法如下:

func BeanchmarkFact(b *testing.B) {
    for i :=0;i <=20000;i++{
        Fact(i)
    }
}

代码块

package codetest

import "testing"

func TestAdd(t *testing.T){
    if 3 != Add(1,2){
        t.Errorf("1加2不等于3")
    }
}

func TestAdd2(t *testing.T){
    if -1 != Add(-1,3){
        t.Errorf("-1")
    }
}


func BeanchmarkFact(b *testing.B) {
    for i :=0;i <=20000 ;i++{
        Fact(i)
    }
}
  • bench

在执行go test的时候 要加-bench参数

[root@linuxea.com /opt/Golang/inTest/codetest]#  go test testmod/codetest  -bench .  
goos: linux
goarch: amd64
pkg: testmod/codetest
BenchmarkFact-2            1    1376384478 ns/op
PASS
ok      testmod/codetest    1.381s
  • benchmem

可以加benchmem查看内存使用

[root@linuxea.com /opt/Golang/inTest/codetest]#  go test testmod/codetest  -bench .  -benchmem
goos: linux
goarch: amd64
pkg: testmod/codetest
BenchmarkFact-2            1    1399430216 ns/op           0 B/op          0 allocs/op
PASS
ok      testmod/codetest    1.403s
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2020-12-10分类: Golang

标签: Golang

发表评论