go语言快速入门:测试覆盖率(18)

来源:互联网 发布:matlab取矩阵中的元素 编辑:程序博客网 时间:2024/05/12 17:35

上篇文章讨论了如何使用testing标准包进行自动化测试,在这篇文章中将进一步细化测试覆盖率的可视化确认。

测试覆盖率

代码测试的覆盖率分很多种,语句覆盖/条件覆盖等等,而在go中,测试覆盖率是这样定义的:Test coverage is a term that describes how much of a package’s code is exercised by running the package’s tests. 可以看出,go语言中的理解是:测试覆盖率是用于通过执行某包的测试用例来确认到的描述其的代码在测试用例中被执行的程度的术语。

项目 URL Cover https://blog.golang.org/cover

统计模式

在go语言的测试覆盖率统计时,go test通过参数covermode的设定可以对覆盖率统计模式作如下三种设定。

模式 解释 set 缺省模式, 只记录语句是否被执行过 count 记录语句被执行的次数 atomic 记录语句被执行的次数,并保证在并发执行时的正确性

测试对象

项目 详细 说明 文件名 basicfunc.go 测试对象文件 package名 basicfunc 测试对象Package 测试对象函数 GetGrade 输入分数返回A-D的等级 测试对象函数 Add 输入两个数字,返回其相加之和

例子代码

[root@liumiaocn test]# cat basicfunc.gopackage basicfuncfunc GetGrade(score int) string {        switch {        case score < 60:                return "D"        case score <= 70:                return "C"        case score <= 80:                return "B"        case score <= 90:                return "A"        default:                return "Undefined"        }}func Add(num1 int, num2 int) int {        return num1 + num2}[root@liumiaocn test]#

功能测试用例

[root@liumiaocn test]# cat func_test.gopackage basicfuncimport "testing"func TestBasic(test *testing.T) {        grade := GetGrade(40)        if grade != "D" {                test.Error("Test Case failed.")        }}func TestAddfunc(test *testing.T) {        sum := Add(1, 1)        if sum == 2 {                test.Log("Passed: 1 + 1 == 2 ")        } else {                test.Log("Failed: 1 + 1 == 2 ")        }}[root@liumiaocn test]#

覆盖率确认

注意事项

当go test命令无法正常运行时,学习时请将测试对象package放到GOROOT下,比如

[root@liumiaocn test]# echo $GOROOT/usr/local/go[root@liumiaocn test]# pwd/usr/local/go/src/goprj/test[root@liumiaocn test]#

确认覆盖率

[root@liumiaocn test]# go test -coverPASScoverage: 42.9% of statementsok      goprj/test      0.007s[root@liumiaocn test]#

HTML方式

可以看到我们现在得到了一个42.9%的覆盖率,这说明42.9%的代码在测试用例执行中被至少执行过一次。但是想确认那些语句没有被执行的时候,上述方法就无法使用了。接下来我们将继续使用go test命令生成html文件用以显示测试覆盖率情况。

生成HTML前的准备

哪个文件的哪行代码被执行了的中间信息如果没有的话,无论什么工具也会无能为力。所以第一步就是要生成这些中间的信息。

[root@liumiaocn test]# pwd/usr/local/go/src/goprj/test[root@liumiaocn test]# go test -coverprofile=covprofilePASScoverage: 42.9% of statementsok      goprj/test      0.007s[root@liumiaocn test]# cat covprofilemode: setgoprj/test/basicfunc.go:3.33,4.16 1 1goprj/test/basicfunc.go:5.9,6.27 1 1goprj/test/basicfunc.go:7.9,8.27 1 0goprj/test/basicfunc.go:9.9,10.27 1 0goprj/test/basicfunc.go:11.9,12.27 1 0goprj/test/basicfunc.go:13.9,14.35 1 0goprj/test/basicfunc.go:18.34,20.2 1 1[root@liumiaocn test]#

可以看到生成的中间文件covprofile中覆盖率统计模式为set,同时还有很多统计信息。

生成HTML文件

[root@liumiaocn test]# go tool cover -html=covprofile -o coverage.html[root@liumiaocn test]#

生成的HTML文件内容

[root@liumiaocn test]# cat coverage.html<!DOCTYPE html><html>        <head>                <meta http-equiv="Content-Type" content="text/html; charset=utf-8">                <style>                        body {                                background: black;                                color: rgb(80, 80, 80);                        }                        body, pre, #legend span {                                font-family: Menlo, monospace;                                font-weight: bold;                        }                        #topbar {                                background: black;                                position: fixed;                                top: 0; left: 0; right: 0;                                height: 42px;                                border-bottom: 1px solid rgb(80, 80, 80);                        }                        #content {                                margin-top: 50px;                        }                        #nav, #legend {                                float: left;                                margin-left: 10px;                        }                        #legend {                                margin-top: 12px;                        }                        #nav {                                margin-top: 10px;                        }                        #legend span {                                margin: 0 5px;                        }                        .cov0 { color: rgb(192, 0, 0) }.cov1 { color: rgb(128, 128, 128) }.cov2 { color: rgb(116, 140, 131) }.cov3 { color: rgb(104, 152, 134) }.cov4 { color: rgb(92, 164, 137) }.cov5 { color: rgb(80, 176, 140) }.cov6 { color: rgb(68, 188, 143) }.cov7 { color: rgb(56, 200, 146) }.cov8 { color: rgb(44, 212, 149) }.cov9 { color: rgb(32, 224, 152) }.cov10 { color: rgb(20, 236, 155) }                </style>        </head>        <body>                <div id="topbar">                        <div id="nav">                                <select id="files">                                <option value="file0">goprj/test/basicfunc.go (42.9%)</option>                                </select>                        </div>                        <div id="legend">                                <span>not tracked</span>                                <span class="cov0">not covered</span>                                <span class="cov8">covered</span>                        </div>                </div>                <div id="content">                <pre class="file" id="file0" style="display: none">package basicfuncfunc GetGrade(score int) string <span class="cov8" title="1">{        switch </span>{        <span class="cov8" title="1">case score &lt; 60:                return "D"</span>        <span class="cov0" title="0">case score &lt;= 70:                return "C"</span>        <span class="cov0" title="0">case score &lt;= 80:                return "B"</span>        <span class="cov0" title="0">case score &lt;= 90:                return "A"</span>        <span class="cov0" title="0">default:                return "Undefined"</span>        }}func Add(num1 int, num2 int) int <span class="cov8" title="1">{        return num1 + num2}</span></pre>                </div>        </body>        <script>        (function() {                var files = document.getElementById('files');                var visible;                files.addEventListener('change', onChange, false);                function select(part) {                        if (visible)                                visible.style.display = 'none';                        visible = document.getElementById(part);                        if (!visible)                                return;                        files.value = part;                        visible.style.display = 'block';                        location.hash = part;                }                function onChange() {                        select(files.value);                        window.scrollTo(0, 0);                }                if (location.hash != "") {                        select(location.hash.substr(1));                }                if (!visible) {                        select("file0");                }        })();        </script></html>[root@liumiaocn test]#

结果确认

将生成的HTML用浏览器打开,可以很清楚地看到测试用例覆盖的代码和未曾覆盖到的代码,一目了然。
这里写图片描述

参考文献

项目 URL Cover https://blog.golang.org/cover
0 0
原创粉丝点击