gcov lcov genhtml工具

     gcov伴随gcc 发布。gcc编译加入-fprofile-arcs -ftest-coverage 参数生成二进制程序,执行测试用例生成代码覆盖率信息。

使用这些工具产生代码覆盖率的统计,需要经过:编译参数设置&编译、运行、gcov生成覆盖信息、locv生成 html报表数据、genhtml根据报表数据生成可视化的html报告 这几个步骤

编译参数设置&编译

    用GCC编译的时候加上-fprofile-arcs -ftest-coverage选项,链接的时候也加上。
    fprofile-arcs参数使gcc创建一个程序的流图,之后找到适合图的生成树。只有不在生成树中的弧被操纵(instrumented):gcc添加了代码来清点这些弧执行的次数。当这段弧是一个块的唯一出口或入口时,操纵工具代码(instrumentation code)将会添加到块中,否则创建一个基础块来包含操纵工具代码。

    编译成功后,会生成各*.c对应的 *.gcno文件。*.gcno是由-ftest-coverage产生的,它包含了重建基本块图和相应的块的源码的行号的信息。

运行

    也就是执行单元测试进程,如果编译参数中加了gcov相关的参数后,执行结果会生成 各 *.c文件对应的 *.gcda文件。*gcda是由加了-fprofile-arcs编译参数的编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息(而gcda只能在程序运行完毕后才能产生的)。

 

gcov生成覆盖信息

     Gcov执行函数覆盖、语句覆盖和分支覆盖。gcov工具会生成各*.c文件对应的 *.c.gcov 文件,不过*.c.gcov在lcov命令执行后,会被删除。*.c.gcov包含了函数和代码执行次数的信息。

locv生成 html报表数据

Lcov则是上的gcov 结果展现的一个前端,可以将覆盖率信息转换成html展现,它用来解析*.c.gcov中晦涩的字符,生成代码覆盖的信息,并输出到文件(*.info),genhtml根据*.info文件生成html报告。

  1. lcov -d ./ -c -o $(LCOV_INFO) -b ./

 

genhtml根据报表数据生成可视化的html报告

  1. genhtml -o $(COV_REPORT) $(LCOV_INFO) --show-details legend

 

最终的报告,*.html文件

 

 

完整的makfile

  1. # makefile for sample cpputest
  2.  
  3. INC_DIR := -I../inc -I../inc/mysql -I../src/libcas
  4. SRC_FILE := libcas.c cJSON.c qs_thread.c qs_init.c qs_paltask.c qs_cmd.c qs_db.c qs_main.c
  5. SRC_OBJS := libcas.so
  6. SRC_LNAME := cas
  7.  
  8. TEST_GROUP_FILE := test.c mocks.c
  9. TEST_EXE := test_libcas
  10.  
  11. RUN_PREPARE := "cp ../bin/cas.json ."
  12.  
  13. UT_LOG := result.log
  14. CU_PROJECT_NAME := $(shell pwd |awk -F "/" '{print $$NF}' )
  15. LCOV_INFO := $(CU_PROJECT_NAME).info
  16. COV_REPORT := $(CU_PROJECT_NAME)_cover
  17.  
  18. all: $(TEST_EXE) $(SRC_OBJS)
  19.  
  20. CPPUTEST_HOME := /usr/cpputest
  21.  
  22. CC := gcc -Wformat
  23. CCFLAGS := -g -DLINUX $(INC_DIR) -shared -fPIC -fprofile-arcs -ftest-coverage --coverage
  24. CCFLAGS += -D CPPUTEST # 编译测试文件时, 忽略被测代码 *.c 的main函数, test.c 的代码中用了宏CPPUTEST
  25. CCLDFLAGS := -lgcov
  26. CCLDFLAGS += -L../bin -lm -lvst_memory -lvst_shell_log -ldbase_comm -lbase_log -lvst_plat -lpthread \
  27. -loam_proxy -ldbase_my
  28.  
  29. CPP := g++
  30. CPPFLAGS := -g -w -fpermissive -DLINUX -fprofile-arcs -ftest-coverage --coverage
  31. CPPFLAGS += -I$(CPPUTEST_HOME)/include $(INC_DIR)
  32. CPPLDFLAGS := -lgcov
  33. CPPLDFLAGS += -Wl,-rpath,./,-rpath,./../bin -L$(CPPUTEST_HOME)/lib -L../bin -lCppUTest -lCppUTestExt
  34. CPPLDFLAGS += -lssl -ldl -lpthread -lvst_com -lvst_memory -lvst_plat -lvst_encrypt\
  35. -lvst_shell_cli -lvst_shell_log -lm -lvst_thpool -lreadline \
  36. -lvst_thpool -ldbcfg_parse -ldata_parse \
  37. -lipdr -laccpwd -lstat -luas -ldata_stat
  38.  
  39. CPPLDFLAGS += -l$(SRC_LNAME)
  40.  
  41. SRCDIR := $(shell ls -d ../src/*)
  42. vpath
  43. vpath %.c $(SRCDIR)
  44.  
  45. $(SRC_OBJS): $(SRC_FILE)
  46. $(CC) -o $@ $^ $(CCFLAGS) $(CCLDFLAGS)
  47.  
  48. $(TEST_EXE): $(TEST_GROUP_FILE) $(SRC_OBJS)
  49. $(CPP) -o $@ $^ $(CPPFLAGS) $(CPPLDFLAGS)
  50.  
  51. .PHONY: clean
  52. clean:
  53. @echo "clean..."
  54. rm -f $(SRC_OBJS) $(TEST_EXE)
  55. rm -f *.gcda
  56. rm -f *.gcno
  57. rm -f *.gcov
  58. rm -f $(UT_LOG)
  59. rm -rf $(COV_REPORT)
  60. rm -f *.info
  61.  
  62. run:
  63. eval $(RUN_PREPARE)
  64. ./$(TEST_EXE) &> $(UT_LOG)
  65.  
  66. cover:
  67. for file in $(SRC_FILE);\
  68. do\
  69. gcov -b "$$file";\
  70. done
  71. lcov -d ./ -c -o $(LCOV_INFO) -b ./
  72. genhtml -o $(COV_REPORT) $(LCOV_INFO) --show-details --legend

 

一些问题

一开始的时候,生成的报告,只有 line和functions的统计,没有branches的统计。

在执行 make cover后,日志只有:

gcov命令执行的日志中,有branch的信息:

开始解决问题的思路:是不是gcov 或lcov的命令参数不对,查了命令及尝试了修改参数后,仍未解决。

后来发现 lcov的命令日志中有如下告警:

按告警信息搜索,发现了 stackoverflow上有个相似的问题:

http://stackoverflow.com/questions/13378640/lcov-can-not-collect-branch-coverage-statistics

参照上面的思路,修改了/etc/lcovrc中

lcov_branch_coverage=1

genhtml_branch_coverage=1

后,最终的html报告中才有branches的统计。

c/c++代码的unit-test中覆盖率的统计的更多相关文章

  1. Mysql基础代码(不断完善中)

    Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...

  2. php示例代码之类似于C#中的String.Format方法

    php示例代码之类似于C#中的String.Format方法 原文来自于  http://stackoverflow.com/questions/1241177/c-string-format-equ ...

  3. 利用Roslyn把C#代码编译到内存中并进行执行

    Tugberk Ugurlu在其博文<Compiling C# Code Into Memory and Executing It with Roslyn>中给大家介绍了一种使用.NET下 ...

  4. ASP.net中网站访问量统计方法代码(在线人数,本月访问,本日访问,访问流量,累计访问)

    一.建立一个数据表IPStat用于存放用户信息 我在IPStat表中存放的用户信息只包括登录用户的IP(IP_Address),IP来源(IP_Src)和登录时间 (IP_DateTime),些表的信 ...

  5. mac github工具将命令当下来的代码拖入macgithub中就可以

    mac github工具将命令当下来的代码拖入macgithub中就可以,刚開始傻傻的就知道点击那个加入button,总是在当下来的文件夹下创建个文件夹.并且代码不能同步

  6. git使用方法----如何利用git管理代码?如何使用git将代码传到github中去

    ##  在文件夹中打开 git here; 1.git init ===初始化一个仓库(这个仓库会存放,git对我们代码进行备份的文件)2.配置个人信息 -- --在git中设置当前使用的用户是==( ...

  7. .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中

    不知你是否见过 try { } finally { } 代码中,try 块留空,而只往 finally 中写代码的情况呢?这种写法有其特殊的目的. 本文就来说说这种不一样的写法. 你可以点开这个链接查 ...

  8. Google自动广告,将广告代码放置在 HTML 中的什么位置?

    Google自动广告,将广告代码放置在 HTML 中的什么位置? 为自动广告生成广告代码后,您需要将此代码放置在要展示广告的每个网页中.您应将广告代码放置在网页的 <head> 标记(或正 ...

  9. Java用代码演示String类中的以下方法的用法

    用代码演示String类中的以下方法的用法 (1)boolean isEmpty(): 判断字符串是不是空串,如果是空的就返回true (2)char charAt(int index): 返回索引上 ...

随机推荐

  1. 【bzoj4530】大融合(LCT的子树维护)

    LCT维护子树并没有想象中的那么难,在这里只是复习下. (其他的维护子树的题目,可见:“共价大爷游长沙”) 只要记录下虚边连接的信息就好了. #include<bits/stdc++.h> ...

  2. Python简单的制作图片验证码

    -人人可以学Python--这里示范的验证码都是简单的,你也可以把字符扭曲 人人可以学Python.png Python第三方库无比强大,PIL 是python的一个d第三方图片处理模块,我们也可以使 ...

  3. [LabVIEW架构]ActorFramework(二)

    前言 在上一个文章中,我们介绍了一下LabVIEW中AF的基本概念,本讲将以上一次的例子来讲解LabVIEW中的实现 正文 范例说明 假定两个人,一个作为老师,一个作为学生.学生每天早上给老师发送一封 ...

  4. ios IAP 内购验证

    参考我之前的笔记 苹果内购笔记,在客户端向苹果购买成功之后,我们需要进行二次验证. 二次验证 IOS在沙箱环境下购买成功之后,向苹果进行二次验证,确认用户是否购买成功. 当应用向Apple服务器请求购 ...

  5. php中mvc新建页面

    PHP配置: <?phpclass appointmentController extends Controller{public function __construct(){parent:: ...

  6. [USACO06NOV]路障---严格次短路

    Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她的旅途,于是她每次回农场,都会选择第二短的路径,而不象我们所习惯的那样, ...

  7. 0,null,undefined,[],{},'',false之间的关系

    0与一些虚值的比较: 0与false 0==false true 0与'': =='' true 0与[]: ==[] true 0与NaN: 0==NaN false 0与undefined 0== ...

  8. IEDA自动清除无用的import

    Before After Step     快捷键展示格式化对话框:ctrl + shift + alt + l   格式化快捷键:ctrl + alt + l <wiz_tmp_tag id= ...

  9. Decode Ways——动态规划

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  10. .net core 2.0学习记录(四):Middleware使用以及模拟构建Middleware(RequestDelegate)管道

    .net Core中没有继续沿用以前asp.net中的管道事件,而是开发了一个新的管道(Middleware): public class MiddlewareDemo { private reado ...