小编前期所测项目多为go语言研发,为了获取自动化测试代码覆盖率及报告,调研并使用go test进行覆盖率统计。现将实战过程留档,并分享出来以供有需要小伙伴参考。
获取流程如下:
各个阶段详细介绍有:
1、创建main函数的test文件
想要获取覆盖率,首先要创建main.go文件相应测试文件main_test.go,在main_test.go中使用一个端口,该端口可以控制服务在运行完测试用例后退出并将内存中的覆盖率信息写入文件。端口写在源码中,使得每次修改都要重新编译才生效。此处使用配置文件管理控制端口,修改方便且直观。该控制端口在配置文件main_test_port.toml中管理,配置文件格式举例有:
[common] port = 8888
main_test.go中控制逻辑有监听端口,接收到信号后主动提出应用。写出main_test.go完整内容。
func startServer(){ go main(); } 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 is accessed http.HandleFunc(“/”, testHandler) fdir := getExecutePath() fpath := fdi+ “/../conf/testing/main_test_port.toml” var conf Config if _, err := toml.DecodeFile(fpath, &conf); err != nil { fmt.Println(“decode config file err”) } port := conf.Common.Port go http.ListenAndServe(“:” + port, nil) exitChan = make(chan int) sigChan := make(chan os.Signal) signal.Notify(sigChan, os.Interrupt) select{ case sig := <-sigChan: 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 –c –covermode=count -coverpkg src –o main.test
其中,-o main.test指定编译产出的名称为main.test;-covermode指定覆盖模式,count标识记录语句执行;coverpkg 指定统计的源码目录集合,各项之间以英文逗号连接。
3、运行主服务
命令行格式运行打桩版本编译产出,并指定生成覆盖率统计数据写入coverage.out中,指定命令如下。
./main.test –test.coverprofile coverage.out
服务启动后,占用两个端口:一个为原本可接受http请求的端口;另外一个为步骤1中使用的控制端口。
4、执行测试用例
执行项目自动化用例。小编所在团队用例使用robot编写,此处可通过平台或者命令行执行可用用例。
5、优雅退出主服务,并生成覆盖率报告
向控制端口发送中断信号后,主服务优雅退出,并生成步骤3中指定命名为coverage.out的覆盖率文件。通过curl命令发送中断信息,命令有
curl ip:port
其中,ip为服务运行机器的ip地址;port为步骤1中指定的控制端口。
当前生成的coverage.out文件仅记录各个文件的覆盖行数等信息,可读性差。通过现用工具将coverage.out作为数据源,为每个源码文件生成一个对应的html报告文件,样式见下图。
其中,各行通过不同颜色标识是否被覆盖,绿色标识被覆盖,红色表示未覆盖。
为了使得各个服务的各个版本的覆盖率报告可历史遍历,可将数据留档至数据库中,将实现一个前端平台展示。
作者:郝继飞
来源:51Testing软件测试网原创