社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
fun Test[FuncName](t *testing.T)
,基准测试func Benchmark[FuncName](b *testing.B)
go test .
,基准测试go test -bench .
代码示例:
func TestTriangle(t *testing.T) {
tests := []struct {a, b, c int} {
{3, 4, 5},
{5, 12, 13},
{8, 15, 17},
{12, 35, 37},
{30000, 40000, 50000},
}
for _, tt := range tests {
// callTriangle 求直角边函数
if actual := callTriangle(tt.a, tt.b); actual != tt.c {
t.Errorf("callTriangle(%d, %d);" +
"got %d; expected %d", tt.a, tt.b, actual, tt.c)
}
}
}
// 基准测试
func BenchmarkTriangle(b *testing.B) {
x, y, z := 30000, 40000, 50000
for i:=0; i<b.N; i++ {
if actual := callTriangle(x, y); actual != z {
b.Errorf("callTriangle(%d, %d);" +
"got %d; expected %d", x, y, actual, z)
}
}
}
在Go语言中比较推崇表格驱动测试,因为和普通的测试相比,表格驱动测试有如下优点:
代码示例:上面第一个测试就是表格驱动测试
测试的覆盖率写到c.out上,并使用go tool输出到网页中。
go test -coverprofile=c.out
go tool cover -html=c.out
效果:绿色表示测试覆盖到的代码
通过go提供的工具来对代码进行性能上的分析。先将cpu性能分析文件输出cpu.out
,再用pprof
工具对cpu.out
进行查看。
被测试代码
// 求最短不重复子串
func lengthOfNonRepeatingSubStr(s string) int {
lastOccurred := make(map[rune]int)
start := 0
maxLength := 0
for i, ch := range []rune(s) {
if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
start = lastI + 1
}
if i-start+1 > maxLength {
maxLength = i - start + 1
}
lastOccurred[ch] = i
}
return maxLength
}
func BenchmarkNoeepeating(b *testing.B) {
s := "黑化肥挥发发灰会花飞灰化肥挥发发黑会飞花"
for i:=0; i<13; i++ {
s = s + s }
ans := 8
for i:=0; i<b.N; i++ {
if l := lengthOfNonRepeatingSubStr(s); l != ans {
b.Errorf("got %d for input %s;" +
"expected %d",
l, s, ans)
}
}
}
终端执行代码如下:
go test -bench . -cpuprofile cpu.out
go tool pprof cpu.out
执行完上面的语句会进入pprof
内部的命令行。
最简单的分析方式就是使用web
输出成svg文件进行查看。如果该指令没有效果说明没有安装graphviz
工具输入sudo apt install graphviz
即可。然后再运行web
就可以看到下图:
图中会显示函数运行过程中调用了哪些模块,每个模块在运行过程中消耗了cpu资源的占比。
通过上面的图可以查看,比如上面代码中改用slice
会更快。
方式:
代码示例:完整代码
var tests = []struct {
h appHandler
code int
message string
}{
{errPanic, 500, "Internal Server Error"},
{errUserError, 400, "user error"},
{errNotFound, 404, "Not Found"},
{errNotPermission, 403, "Forbidden"},
{errUnknown, 500, "Internal Server Error"},
{noError, 200, "no error"},
}
func TestErrWrapper(t *testing.T) {
for _, tt := range tests {
f := errWrapper(tt.h)
response := httptest.NewRecorder()
request := httptest.NewRequest(
http.MethodGet,
"http://www.imooc.com", nil)
f(response, request)
verifyResponse(response.Result(), tt.code, tt.message, t)
}
}
func TestErrWrapperInServer(t *testing.T) {
for _, tt := range tests {
f := errWrapper(tt.h)
server := httptest.NewServer(http.HandlerFunc(f))
resp, _ := http.Get(server.URL)
verifyResponse(resp, tt.code, tt.message, t)
}
}
func verifyResponse(resp *http.Response, expectedCode int,
expectedMsg string, t * testing.T) {
b, _ := ioutil.ReadAll(resp.Body)
body := strings.Trim(string(b), "n")
if resp.StatusCode != expectedCode || body != expectedMsg {
t.Errorf("expect (%d, %s);"+
"got (%d, %s)",
expectedCode, expectedMsg,
resp.StatusCode, body)
}
}
直接是用godoc查看文档
需要在函数末端添加注释,// Output:然后后面每一行按上面的输出顺序写好结果,运行就可以测试该函数是否和运行的结果是一样的。
func ExampleQueue_Pop() {
q := Queue{}
q.Push(23)
q.Push(59)
q.Push(5)
fmt.Println(q.Pop())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
fmt.Println(q.Pop())
fmt.Println(q.IsEmpty())
// Output:
// 23
// 59
// false
// 5
// true
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!