Go语言9-测试和性能

测试驱动开发推荐编写测试-运行测试-实现-运行测试-重构-运行测试的的开发流程。开发过程中就进行单元测试和基准测试,在GO语言中也一样可以。go提供了go test命令进行测试。

在 Go 语言里有几种方法写单 测试。 basic test 只使用一组参数和结果来测试 一段代码。 组 table test 也会测试一段代码,但是会使用多组参数和结果进行测试。也 可以使用一些方法来模 (mock)测试代码需要使用到的外部资源,如数据库或者网络服务器。

单元测试

先看示例: 要测试的代码hello.go

package hello
import (
	"strconv"
)
func Add(a, b string) (int, error) {
	x, err := strconv.Atoi(a)
	if err != nil {
		return 0, err
	}
	y, err := strconv.Atoi(b)
	if err != nil {
		return 0, err
	}
	return x + y, nil
}

测试代码hello_test.go

package hello
import (
	"testing"
)
func TestAdd_01(t *testing.T) {
	t.Log("Should return ok: 1+4")
	{
		rst, err := Add("1", "4")
		if err != nil {
			t.Error("error", err)
		}
		if rst == 5 {
			t.Log("return ",rst)
		}else {
			t.Error("wrong return")
		}
	}
}
func TestAdd_02(t *testing.T) {
	t.Log("Should return invalid syntax")
	{
		rst, err := Add("1", "4xx")
		if err != nil {
			t.Log("error", err)
		} else {
			t.Error("test failed", rst)
		}
	}
}

运行测试命令:

$ go test
PASS
ok  	hello	0.007s
$ go test -v
=== RUN   TestAdd_01
--- PASS: TestAdd_01 (0.00s)
	hello_test.go:6: Should return ok: 1+4
	hello_test.go:13: return  5
=== RUN   TestAdd_02
--- PASS: TestAdd_02 (0.00s)
	hello_test.go:20: Should return invalid syntax
	hello_test.go:24: error strconv.Atoi: parsing "4xx": invalid syntax
PASS
ok  	hello	0.007s

根据上述示例,先介绍单元测试的一些规则:

  1. 含有单元测试代码的go文件必须以_test.go结尾,样在执行go test的时候才会执行到相应的代码。
  2. import testing这个包
  3. 所有的测试用例函数必须是Test开头,如TestXXMethod。参数是(t *testing.T)。没有返回值。

表组测试

表组测试除了会有一组不同的输入和期望结果之外,其余部分都很像基础单元测试。

package hello
import (
	"net/http"
)
func GetGithubApiStatus(uri string) (int) {
	resp, err := http.Get(uri)
	if err != nil {
		return 0
	}
	return resp.StatusCode
}

测试代码

package hello
import (
	"testing"
)
func TestGetGithubApiStatus(t *testing.T) {
	var urls = []struct {
		url        string
		statusCode int
	}{
		{
			"https://api.github.com/users/ThoreauZZ",
			200,
		},
		{
			"https://api.github.com/users/ThoreauZY",
			404,
		},
	}
	t.Log("Given url to test response status. ")
	{
		for _, u :=range urls{
			status := GetGithubApiStatus(u.url)
			if status != u.statusCode {
				t.Error("Test failed, status is ",u)
			}
		}
	}
}

TODO 待续mock和性能测试


参考 [1]. 《go语言实战》

CONTENTS