正文
(
https://godoc.org/net/http/httptrace)
它提供了一种调试HTTP请求和响应的方式。你可以像下面这样轻易地获取基于HTTP协议的通讯过程的详细信息。
本文代码部分较长,建议在PC端浏览。
package main
import (
"context"
"fmt"
"log"
"net/http"
"net/http/httptrace"
"os"
)
func main() {
traceCtx := httptrace.WithClientTrace(context.Background(), &httptrace.ClientTrace{
GetConn: func(hostPort string) {
fmt.Printf("Prepare to get a connection for %s.\n", hostPort)
},
GotConn: func(info httptrace.GotConnInfo) {
fmt.Printf("Got a connection: reused: %v, from the idle pool: %v.\n",
info.Reused, info.WasIdle)
},
PutIdleConn: func(err error) {
if err == nil {
fmt.Println("Put a connection to the idle pool: ok.")
} else {
fmt.Println("Put a connection to the idle pool:", err.Error())
}
},
ConnectStart: func(network, addr string) {
fmt.Printf("Dialing... (%s:%s).\n", network, addr)
},
ConnectDone: func(network, addr string, err error) {
if err == nil {
fmt.Printf("Dial is done. (%s:%s)\n", network, addr)
} else {
fmt.Printf("Dial is done with error: %s. (%s:%s)\n", err, network, addr)
}
},
WroteRequest: func(info httptrace.WroteRequestInfo) {
if info.Err == nil {
fmt.Println("Wrote a request: ok.")
} else {
fmt.Println("Wrote a request:", info.Err.Error())
}
},
GotFirstResponseByte: func() {
fmt.Println("Got the first response byte.")
},
})
req, err := http.NewRequest("GET", "http://www.golang.org/", nil)
if err != nil {
log.Fatal("Fatal error:", err)
}
req = req.WithContext(traceCtx)
_, err = http.DefaultClient.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "Request error: %v\n", err)
os.Exit(1)
}
}
强烈建议你动手运行一下这个小程序,享受一下掌控全局的感觉。
Go 1.7中增加了对子测试(
https://blog.golang.org/subtests
)的支持,包括功能测试和性能测试。子测试的主要目的是在测试函数中区分和展示因不同的测试参数或测试数据带来的不同的测试结果。请看下面的测试程序。
package subtest
import (
"fmt"
"math/rand"
"strconv"
"testing"
)
// KE 代表键-元素对。
type KE struct {
key string
element int
}
// BenchmarkMapPut 用于对字典的添加和修改操作进行测试。
func BenchmarkMapPut(b *testing.B) {
max := 5
var kes []KE
for i := 0; i
在程序所在目录下使用go test -run=^$ -bench .命令运行它之后就会看到,针对每一个子测试,go test命令都会打印出一行测试摘要。它们是分离的、独立统计的。这可以让我们进行更加精细的测试,细到每次输入输出。上述打印内容类似:
BenchmarkMapPut/Key:_0425,_Element:_498081-4 30000000 40.6 ns/op
BenchmarkMapPut/Key:_1540,_Element:_727887-4 30000000 41.7 ns/op
BenchmarkMapPut/Key:_2456,_Element:_131847-4 30000000 43.3 ns/op
BenchmarkMapPut/Key:_3300,_Element:_984059-4 30000000 46.1 ns/op
BenchmarkMapPut/Key:_4694,_Element:_902081-4 30000000 48.4 ns/op
BenchmarkMapPut/Key:_5511,_Element:_941318-4 30000000 59.3 ns/op
PASS
ok _/Users/haolin/infoq-2016_review_go /demo/subtest 8.678s
在Go 1.5的时候,官方启用了一个新的环境变量——GO15VENDOREXPERIMENT。该环境变量可以启动Go的vendor目录(https://golang.org/s/go15vendor) 并用于存放当前代码包依赖的代码包。在Go 1.5中,若GO15VENDOREXPERIMENT的值为1则会启动vendor目录。
Go 1.6正相反,默认支持vendor目录,当GO15VENDOREXPERIMENT的值为0时禁用vendor目录。到了Go 1.7,官方完全去掉了这个环境变量。这也代表着对vendor目录的正式支持。Go语言的实验特性一般都是按照类似的路数一步步迈向正式版的。