代码覆盖率,也称为测试覆盖率,可衡量⾃动化测试执⾏的代码⽐例。

代码覆盖率⼯具针对特定的编程语⾔。 其使⽤⼀系列标准衡量覆盖率,包括代码⾏数、⽅法或函数、分⽀和条件。 您可以使⽤代码覆盖率⼯具识别代码库尚未被⾃动化测试覆盖的部分。

监测代码覆盖率指标有助于确保您保持⾜够的⾃动化测试⽔平。 如果代码覆盖率有所下降,则可能表明您没有将⾃动化测试作为编写新代码的核⼼要素。

然⽽,虽然代码覆盖率能够说明测试覆盖了多少代码,但它并不会指示这些测试的有效性或其能否解决所有故障模式。 将代码覆盖率与其他指标相结合,了解⾃动化测试体系的有效性。

⽐如针对下⾯的代码:

func Div(a, b int) int {
    return a / b
}

单元测试代码如下:

func TestDiv(t *testing.T) {
    v := Div(200, 100)
    if v != 2 {
        t.Errorf("expect 2 but got %d", v)
    }
}

虽然代码覆盖率是百分之百( return a/b 被覆盖率),但是并不是所有的逻辑分⽀都被覆盖了(Div(200,0)就没有被测试,它会panic。但是代码覆盖率确实是⼀个很好的衡量代码质量的⼀个指标,⾄少,较少的代码覆盖率吧意味着程序中还很很有的代码并没有被测试到。

举⼀个⾮Go语⾔的例⼦。SQLite是⼀个⾮常流⾏的嵌⼊式数据库,它专⻔有[⽂章](How SQLite Is Tested)介绍它的测试。它⼤概有151.3 KSLOC( 排除了空格和注释的千⾏代码)代码,⽽测试代码是92038.3 KSLOC, 是逻辑代码的608倍。100%的代码覆盖率。

再⽐如grpc,它的代码覆盖率也是⾮常的⾼(如下图,绿⾊越浓越代码此package或者⽂件代码覆盖率越⾼,越红代表覆盖率越低)。

在第四章我们已经介绍了单元测试的⼏个参数:

  • -cover: 开启代码覆盖率分析
  • -covermode: 分析代码覆盖率模式。 这个模式的不同的设置,会影响统计的结果。⽐如set,只是统计代码是否被覆盖。count还是统计代码⾏覆盖的数量,atomic针对并发测试的统计。
  • -coverpkg: 分析指定的package。指定coverpkg好处是它能够跨package统计代码覆盖率, 这篇⽂章Get Accurate Code Coverage in Go做了详细的测试。最好这个设置成 -coverpkg=./... ⽽不是 -coverpkg=all

⽣成测试报告

为了更⽅便查看各单元测试的细节,go提供了⼯具,可以把代码覆盖率⽣成⽹⻚查看。

go tool cover -html=cover.out -o cover.html

然后打开cover.html查看各个⽂件的单侧覆盖情况。如果是covermode=count,还可以显示代码⾏覆盖的次数的多少。

这种⻛格很像90年代的⽹⻚样式,真的应该好好设计⼀下⽹⻚样式。不过Go已经发布⼗多年了,居然⼏乎没有⼈对此下⼿,这着实奇怪。

有⼈也提供了将⿊⾊转换成明亮⾊的⽅式:

go tool cover -o cover2.html -html=cover.out; sed -i'*.bak'
's/black/whitesmoke/g' cover2.html; rm -fr cover2.html*.bak

其中 *.bak 是为了在MacOS也能执⾏,在Linux环境下 -i'*.bal' 是不需要的。

⽣成更漂亮的测试报告

matm/gocov-html提供了⼀种⽣成junit⻛格的代码覆盖率的⽅法。它使⽤axw/gocov⼯具⽣成的测试结果,转换成junit⻛格的⽹⻚。当然gocov也能把go cover⽣成的测试结果转换成它的格式。

⽣成treemap图

为了看⼀个项⽬的整体的代码状况,我推荐你使⽤nikolaydubina/go-cover-treemap,它可以⽣成漂亮的SVG treeamap图,如上⾯的grpc的代码覆盖率图。

只需要三步就可以⽣成相应的图。

  1. 安装go-cover-treemap⼯具
  2. 使⽤go test⽣成代码覆盖率数据
  3. 转换数据为svg treemap图
$ go install github.com/nikolaydubina/go-cover-treemap@latest
$ go test -coverprofile cover.out ./...
$ go-cover-treemap -coverprofile cover.out > out.svg
作者:admin  创建时间:2024-10-22 01:55
最后编辑:admin  更新时间:2024-10-22 02:07