go语言中常用的功能之十一(单元测试和案例测试)

go语言常见的单元测试和案例测试

1. 单元测试

go中的测试比较简单,遵循以下几点即可:

  1. 测试文件以源文件名_test.go 命名
  2. 测试函数名称格式以 TestFuncName(t *testing.T) 命名
  3. 测试错误 t.Error / t.Fail / t.Errorf 记录
  4. 测试日志 t.Log 记录

我们来看一个例子
calc.go

package calc

func Dec(a, b int) int {
	return a - b
}

calc_test.go

package calc

import "testing"

func TestDec(t *testing.T) {
	a, b := 3,1
	except := a - b
	fact := Dec(a,b)
	if except != fact {
		t.Errorf("%d - %d except %d but fact %d \n",a,b,except,fact)
	}
	t.Log("success")
}

打印结果:

=== RUN   TestDec
--- PASS: TestDec (0.00s)
    calc_test.go:12: success
PASS

2. 测试表

而事实上,我们要测试某个函数通常需要覆盖性的提供多组数据,一个一个写特别麻烦,这就用到了测试表

我们改写 calc_test.go 如下:

func TestDec(t *testing.T) {
	tables := []struct{
		a int
		b int
		res int
	}{
		{1,2,1},
		{5,4,1},
		{24,4,10},
		{255,171,74},
	}
	for _, except := range tables {
		fact := Dec(except.a,except.b)
		if except.res != fact {
			t.Errorf("%d - %d except %d but fact %d \n",except.a,except.b,except.res,fact)
		}
	}
}

我故意写错了三个结果,测试打印如下:

=== RUN   TestDec
--- FAIL: TestDec (0.00s)
    calc_test.go:19: 1 - 2 except 1 but fact -1 
    calc_test.go:19: 24 - 4 except 10 but fact 20 
    calc_test.go:19: 255 - 171 except 74 but fact 84 
FAIL

3. 代码覆盖

单元测试的另一个重要指标就是代码覆盖率,代码覆盖率可以判断测试的完备性,即考虑到了各种可能的类型

我们稍微改动一下calc.go

package calc

func Dec(a, b int) int {
	res := a - b
	if res < 0 {
		return 0 
	} 
	return res 
}

然后我们将 calc_test.go 中的测试数据更改为

tables := []struct{
		a int
		b int
		res int
	}{
		{5,4,1},
		{24,4,10},
	}

执行 :

go test calc -cover

注意: 这里的calc 是基于GOPATHGOROOT 的,比如:
GOPATH : e:/gowork
calc_test.go: e:/gowork/src/study/fortest/
那么你的路径就应该写成
go test tudy/fortest -cover
否则会找不到你的测试文件

打印结果:

=== RUN   TestDec
--- FAIL: TestDec (0.00s)
    calc_test.go:17: 24 - 4 except 10 but fact 20 
FAIL
coverage: 75.0% of statements

如果使用GoLand IDE我们还能看到完整的代码覆盖行
在这里插入图片描述
如果你没有IDE,你可以生成 html 也能直观的查看

go test calc -cover -coverprofile=c.out
go tool cover -html=c.out -o coverage.html 

然后在浏览器中打开 coverage.html 即可查看

4. 案例测试

平常写测试都比较懒,想用更少的代码来解决测试的问题,可以使用案例测试,不需要写
繁琐的打印语句和期待对比,这些都要go编译器自己去做

案例测试遵循以下几点:

  1. 测试文件以源文件_example_test.go 命名
  2. 测试函数名称格式以 ExampleFuncName() 命名
  3. 测试结果打印 以下列格式注释:
 // Output:
 // 结果1
 // 结果2
 ...

calc_example_test.go

package calc

import (
	"fmt"
)

func ExampleDec() {
	tables := []struct{
		a int
		b int
	}{
		{5,4},
		{24,10},
	}
	for _, except := range tables {
		fmt.Println(Dec(except.a,except.b))
	}

	// Output:
	// 1
	// 13
}

运行:

go test calc 

打印结果:

=== RUN   ExampleDec
--- FAIL: ExampleDec (0.00s)
got:
1
14
want:
1
13
FAIL

猜你喜欢

转载自blog.csdn.net/wujiangwei567/article/details/87930533
今日推荐