代码覆盖范围通常用作代码质量指标。
一个人可以运行
go test -coverpkg ./... -coverprofile test.cov ./...
并接收一个test.cov
文件,其中包含有关执行过程中代码特定部分的频率的信息。
这是保持测试相关的好工具。
但是,代码覆盖范围也可以帮助您调试大型代码库!
想象一个看似无辜的代码变化导致测试破裂的情况。如果执行中涉及大量代码,则达到根本原因可能是不平凡的。
在较小的情况下,您可以通过调试器浏览所有陈述并比较状态和条件,但是当您有成千上万的陈述时,这种方法并不可行。
代码覆盖范围可以帮助您缩小调试的范围。
这是食谱。先决条件是您有一个通过原始代码通过的测试,并且在新的代码中失败。
收集覆盖范围
收集失败和通过的覆盖范围。
重要的是要在所有包装上收集覆盖范围以具有全面的图片。您可以使用./...
或my-module/...
,github.com/foo/my-module/...
for -coverpkg
。
应用更改并运行测试。
go test -cover -coverpkg ./... -coverprofile new.cover -run ^Test_Foo$ ./path/to/tested/package
然后恢复更改并再次收集覆盖范围。
go test -cover -coverpkg ./... -coverprofile orig.cover -run ^Test_Foo$ ./path/to/tested/package
之后,您最终将有两个文件:orig.cover
和new.cover
。
它们可能很大,但希望不会很大。
覆盖范围的文件可能看起来像这样。
mode: set
github.com/swaggest/jsonschema-go/camelcase.go:14.31,21.22 6 1
github.com/swaggest/jsonschema-go/camelcase.go:21.22,22.27 1 1
github.com/swaggest/jsonschema-go/camelcase.go:22.27,24.4 1 1
github.com/swaggest/jsonschema-go/camelcase.go:26.3,26.27 1 1
github.com/swaggest/jsonschema-go/camelcase.go:26.27,28.4 1 1
github.com/swaggest/jsonschema-go/camelcase.go:30.3,30.27 1 1
.....
第一行说使用了哪种覆盖范围收集方式。
所有其他行描述了代码的跨度(file:start_line.start_col,end_line.end_col
),其中该跨度为语句,并且执行了许多语句。
创建覆盖范围差异
按字母顺序排列的覆盖范围文件,因此它们对diff
友好。
diff orig.cover new.cover > diff.cover
生成的文件看起来可能与此相似。
305c305
< github.com/swaggest/jsonschema-go/helper.go:75.46,78.16 2 1
---
> github.com/swaggest/jsonschema-go/helper.go:75.46,78.16 2 0
307c307
< github.com/swaggest/jsonschema-go/helper.go:82.2,84.46 2 1
---
> github.com/swaggest/jsonschema-go/helper.go:82.2,84.46 2 0
309c309
< github.com/swaggest/jsonschema-go/helper.go:88.2,88.15 1 1
您已经可以发现,在执行语句的数量中,这里的行大部分是不同的。这是我们的线索,即代码中的那些地方是最佳候选人,可以通过调试器更深入地看待。
让我们更方便地跟随和检查。
覆盖范围报告
以<
开头的行表示原始代码,以>
开头的行是关于新代码的。
我们可以从差异
构建过滤的覆盖范围报告为此,我们需要还原mode: set
并从行中删除"< "
或"> "
。
echo "mode: set" > orig_flt.cover && grep "< " diff.cover | sed 's/< //' >> orig_flt.cover
echo "mode: set" > new_flt.cover && grep "> " diff.cover | sed 's/> //' >> new_flt.cover
现在,有两个覆盖范围文件仅包含两个运行之间的差异。
我们可以方便地使用标准go tool cover
进行检查。
go tool cover -html=orig_flt.cover -o orig_flt.html
go tool cover -html=new_flt.cover -o new_flt.html
您可以查看代码的执行方式不同,这可能会导致一个可能是根本原因的想法,或者至少可以在设置调试器中断点的情况下提示。
我希望您喜欢阅读本文,就像我喜欢使用这种方法挖掘Huuuuge代码基础一样。 :)