go覆盖率统计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
go覆盖率统计
被测服务是go服务,测试脚本是python等⾮go语⾔实现,可参考以下两种⽅法实现go服务的测试覆盖率统计。
⽅法⼀:go test ⽅式,不编译⼆进制⽂件
1. 创建main_test.go⽂件
或者与你的 func main(){}⽅法所在的⽂件名同名的test⽂件。
⽐如,有如下main.go⽂件:
package main
import (
"/labstack/echo"
"hello-go/api"
)
func main() {
e := echo.New()
e.GET("/", api.HelloWorld)
e.GET("/api1", api.Api1)
e.GET("/api2", api.Api2)
e.Logger.Fatal(e.Start(":8001"))
}
根据以上main.go⽂件,创建以下main_test.go⽂件
package main
import (
"fmt"
"net/http"
"os"
"os/signal"
"testing"
)
var exitChan chan int
func testHandler(w http.ResponseWriter, req *http.Request) {
exitChan <- 666 }
func startServer() {
go main() // main.gomain
}
func TestExternal(t *testing.T) {
// start server need be tested in separate go thread
go startServer()
// go test starts a dummy http server, which is used to
// end the current go test gracefully when it's accessed.
http.HandleFunc("/", testHandler)
go http.ListenAndServe(":9999", nil)
// go test9999
// 9999
exitChan = make(chan int)
sigChann := make(chan os.Signal)
signal.Notify(sigChann, os.Interrupt)
select {
case sig := <-sigChann:
fmt.Printf("exit as received signal: %v\n", sig)
case val := <-exitChan:
fmt.Printf("exit as received http request: %v\n", val)
}
}
2. 执⾏go test启动服务
进⼊main_test.go所在⽬录,⼀般在代码根⽬录,执⾏go test命令:
go test -coverprofile=cov.out -coverpkg ./... &
# -coverprofile 产出的覆盖率⽂件
# -coverpkg 要统计的覆盖率⽂件源码,可以指定⽂件
# & 后台执⾏
3. 执⾏测试⽤例
curl 127.0.0.1:8001 #服务是否正常启动
curl 127.0.0.1:8001/api1 #测试⽤例1
curl 127.0.0.1:8001/api2 #测试⽤例2
curl 127.0.0.1:9999 #服务停⽌,注意:只有停⽌了服务才能⽣成覆盖率⽂件
4. ⽣成覆盖率报告
在代码根⽬录会⽣成cov.out覆盖率⽂件。
为了⽅便查看和浏览,可将out⽂件转换为html报告进⾏查看,执⾏命令如下:
go tool cover -html cov.out -o index.html
5. 拷贝index.html到本地可查看代码⾏覆盖情况
⽅法⼆:编译出⼆进制⽂件执⾏
1. ⽣成覆盖率⼆进制⽂件的原理介绍(插桩产物)
要运⾏系统测试,需要应⽤程序的编译⼆进制⽂件。
然后,在具有不同配置的不同环境中执⾏此⼆进制⽂件。
Golang提供了⼀种独特的⽅法来⽣成覆盖率⼆进制⽂件,⽽不是go build⽣成的默认⼆进制⽂件。
⽣成的代码覆盖率⼆进制⽂件在每⼀⾏代码后写⼊⼀个唯⼀的计数器,并检查在执⾏⼆进制⽂件后调⽤此计数器的次数。
go test -c -covermode=count -coverpkg ./...
#
# -c 表⽰⽣成测试⼆进制⽂件
# -covermode=count 表⽰⽣成的⼆进制中包含覆盖率计数信息
# -o packagename.test 表⽰覆盖率⼆进制⽂件名
# -coverpkg ./... 表⽰要统计的覆盖率⽂件源码
更多的参数信息可以执⾏go test -help来查看。
2. 创建main_test⽂件
现在我们知道了如何⽣成⼆进制⽂件,我们必须确保⼆进制⽂件将按预期执⾏。
您的代码需要满⾜以下要求,才能按照预期⽣成⼆进制。
package中⾄少有⼀个*_test.go⽂件,否则不会⽣成⼆进制⽂件。
建议创建main_test.go ⽂件,或者与你的func main(){}所在的⽂件名同名的test⽂件,与上⼀个⽅法类似,需要创建⼀个main_test.go⽂件让go test来插桩
main_test.go 同上
该⽂件定义了⼀个systemTest标志,并包含⼀个调⽤main函数的测试⽤例。
运⾏测试⼆进制⽂件开始执⾏测试。
在例⼦中,这意味着调⽤TestExternal,因为这是唯⼀的测试。
运⾏TestExternal 意味着调⽤main(),它将像普通⼆进制⽂件那样启动应⽤程序。
这也就意味着运⾏测试产⽣的⼆进制⽂件与运⾏普通⼆进制⽂件相同,只是运⾏测试产⽣的⼆进制⽂件将会跟踪覆盖率执⾏,也就是我们常说的打桩。
为了防⽌在运⾏单元测试时运⾏此测试,添加了命令⾏标志systemTest。
如果未设置,则不会调⽤main()函数。
⽽要运⾏系统测试,必须在执⾏测试⼆进制⽂件期间通过附加-systemTest来设置标志。
3. ⽣成插桩后的覆盖率⼆进制⽂件
在代码根⽬录执⾏以下命令:
go test -c -covermode=count -coverpkg ./... -o hello.test
执⾏完成后将⽣成⼀个 hello.test⽂件
4. 以打桩⼆进制⽂件启动服务
//启动服务(打桩⼆进制)
./hello.test -systemTest -test.coverprofile cov.out &
5. 执⾏测试case
6. ⽣成覆盖率报告
执⾏完⽤例并停⽌服务后,在代码根⽬录下⽣成覆盖率⽂件cov.out
为了⽅便查看和浏览,可将out⽂件转换为html报告进⾏查看,执⾏命令如下:
go tool cover -html cov.out -o index.html
参考⽂档。