前段时间课程要求对自己写的计算器程序实现缺陷定位,也算认识了一种新的工具和方法。我主要学习了两种工具,一种是 C\C++的缺陷定位工具 gcov ,包含在 gcc 工具链中,另一个是 python 的 coverage.py 库,他提供了命令行工具和编程接口两种使用方法。
Gcov
Gocv 是 GNU 项目中的一个软件,它可以对代码进行覆盖测试,我仅仅只是测试了一下基本的使用方法,原理等其他方面并没有深入探究。
我们创建一个待测试的程序,命名为sample.c
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <stdio.h> int main(int argc, char *argv[]) { int a = 10; if (a >= 5) { printf("%d\n", a); } else { printf("%d\n", a + 1); } }
|
gcc 文档给出的插桩选项有很多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| -p -pg -fprofile-arcs --coverage -ftest-coverage -fprofile-abs-path -fprofile-dir=path -fprofile-generate -fprofile-generate=path -fprofile-info-section -fprofile-info-section=name -fprofile-note=path -fprofile-prefix-path=path -fprofile-update=method -fprofile-filter-files=regex -fprofile-exclude-files=regex -fprofile-reproducible=[multithreaded|parallel-runs|serial] -fsanitize=style -fsanitize-recover -fsanitize-recover=style -fsanitize-trap -fsanitize-trap=style -fasan-shadow-offset=number -fsanitize-sections=s1,s2,... -fsanitize-undefined-trap-on-error -fbounds-check -fcf-protection=[full|branch|return|none|check] -fharden-compares -fharden-conditional-branches -fstack-protector -fstack-protector-all -fstack-protector-strong -fstack-protector-explicit -fstack-check -fstack-limit-register=reg -fstack-limit-symbol=sym -fno-stack-limit -fsplit-stack -fvtable-verify=[std|preinit|none] -fvtv-counts -fvtv-debug -finstrument-functions -finstrument-functions-once -finstrument-functions-exclude-function-list=sym,sym,… -finstrument-functions-exclude-file-list=file,file,… -fprofile-prefix-map=old=new
|
我也没有深究他们每一个的作用,只做了最基本的使用
进行编译,编译中要加上选项-fprofile-arcs -ftest-coverage
其中,-ftest-coverage
是生成.gcno
文件,其中包括了重建的源代码基本块依赖图和基本快的必要信息。而-fprofile-arcs
是让编译器对代码进行插桩,并在链接的时候链接 libgcov.a,虽然我用 ldd 没有看到这个链接,另外,使用--coverage
能代替上述两个参数直接完成。
完成之后,文件夹中应该会出现两个文件
1 2
| ls sample.c sample sample.gcno
|
运行sample
,运行之后会生成一个 sample.gcda
文件。之后执行
可以看到命令行输出
1 2 3
| File 'sample.c' Lines executed:80.00% of 5 Creating 'sample.c.gcov'
|
如果源代码名称和可执行程序名称不一样需要指定,具体如何指定文档里面写了。
运行之后会生成一个 sample.c.gcov
文件,打开文件可以看到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| -: 0:Source:sample.c -: 0:Graph:sample.gcno -: 0:Data:sample.gcda -: 0:Runs:1 -: 1:#include <stdio.h> 1: 2:int main(int argc, char *argv[]) -: 3:{ 1: 4: int a = 10; 1: 5: if (a >= 5) -: 6: { 1: 7: printf("%d\n", a); -: 8: } -: 9: else -: 10: { #####: 11: printf("%d\n", a + 1); -: 12: } -: 13:}
|
每一行的运行次数和没有运行到的行数,如果不想整其他的可以直接从这个文件读取数据了
Coverage.py
coverage是python下的一个测试代码覆盖率的库,官方文档:文档,安装仅需要
具体例子先鸽了,jetbrains的教育认证到期了刚刚申请
使用方法很简单,我们有一个sample.py文件,我们只需要使用
即可(他还可以结合pytest等其他工具使用),他会生成一个sqlLite文件,这个数据库中存有覆盖测试的相关信息,可以通过
即可生成网页报告,它还可以有其他的格式(text,HTML,XML,LCOV,JSON),
coverage.py还提供了api
1 2 3 4 5 6 7 8 9 10 11
| import coverage
cov = coverage.Coverage() cov.start()
cov.stop() cov.save()
cov.html_report()
|
同理还可以使用其他的报告格式