Continuous Code Coverage with gcc, googletest, and Hudson

本文介绍如何使用gcc、gtest和Hudson实现C++代码的连续集成,包括设置环境、生成覆盖率统计数据及在Hudson中集成覆盖率报告的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Continuous Code Coverage with gcc, googletest, and Hudson

Continuous Code Coverage with gcc, googletest, and Hudson

Heres a little recipe for getting code coverage metrics for your C++ unit tests using gcc, googletest and hudson.

Suppose we have a little class that we’d like to get under continuous integration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef PROGRESSSTATE_H_
#define PROGRESSSTATE_H_
 
class ProgressState {
public :
   ProgressState(unsigned int target);
   virtual ~ProgressState();
 
   unsigned int getPercentage();
   void setValue( int value);
private :
   unsigned int m_value;
   unsigned int m_target;
};
 
#endif /* PROGRESSSTATE_H_ */

And here is the implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "ProgressState.h"
 
ProgressState::ProgressState(unsigned int target)
  : m_value(0), m_target(target)
{}
 
ProgressState::~ProgressState(){}
 
void ProgressState::setValue( int value)
{
   if (value < 0){
     m_value = 0;
   }
   else if (value > ( int )m_target){
     m_value = m_target;
   }
   else {
     m_value = value;
   }
}
 
unsigned int ProgressState::getPercentage()
{
   return m_value * 100 / m_target;
}

Continuous Build

First we must install Hudson on the build machine.  Hudson is available for most operating systems and it is pretty easy to install.  Once hudson is up and running we will need to install these plugins from our hudson management console:

  • Git Plugin: To poll the git repository for your code
  • Cobertura Plugin: To gather the test coverage results a publish them with the build

The next step is to create a hudson job for building our project.

“] New Job [Hudson]

New Job [Hudson

Then we need a way for Hudson to get access to the source code.  The typical way to do this is to get hudson to poll from your version control system.  Using git this is pretty easy.

 

HudsonGitConfiguration

HudsonGitConfiguration

One thing to remember is to set up the git user account for the hudson server.  To do this in Ubuntu you need to issue the following commands:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mike@mike-laptop:~$  sudo -s -u hudson
hudson@mike-laptop:~$ cd  /var/lib/hudson/jobs/coverage/workspace
hudson@mike-laptop: /var/lib/hudson/jobs/coverage/workspace ls -al
total 20
drwxr-xr-x 5 hudson nogroup 4096 2010-05-31 22:33  .
drwxr-xr-x 4 hudson nogroup 4096 2010-05-31 22:33 ..
drwxr-xr-x  3 hudson nogroup 4096 2010-05-31 22:33 Debug
drwxr-xr-x 8 hudson  nogroup 4096 2010-05-31 22:33 .git
-rw-r--r-- 1 hudson nogroup 0  2010-05-31 22:33 README
drwxr-xr-x 2 hudson nogroup 4096 2010-05-31  22:33 src
hudson@mike-laptop: /var/lib/hudson/jobs/coverage/workspace $
hudson@mike-laptop: /var/lib/hudson/jobs/coverage/workspace $ git  config user.email "some@email.com"
hudson@mike-laptop: /var/lib/hudson/jobs/coverage/workspace $  git config user.name "hudson"
hudson@mike-laptop: /var/lib/hudson/jobs/coverage/workspace $

Generating the coverage statistics with gcov

To get gcc to instrument the generated binary with coverage and profiling (necessary for branch stats) code we must provide the compile with these two additional options: -fprofile-arcs -ftest-coverage. And we must link the final executable with -lgcov. Now when the coverage test executable is run it will output .gcda and .gcno files with the coverage statistics.  These settings are set in the makefiles for the project.

Write some tests

Breaking from TDD conventional wisdom for the purposes of this article, lets write some tests for the production code we already have.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include  <gtest/gtest.h>
#include "ProgressState.h"
 
TEST(ProgressStateTest,  zeroValueOfValidTargetIsZeroPercent)
{
   ProgressState  progress(100);
   progress.setValue(0);
   ASSERT_EQ((unsigned int ) 0,  progress.getPercentage());
}
 
TEST(ProgressStateTest,  negativeValueOfValidTargetIsZeroPercent)
{
   ProgressState  progress(100);
   progress.setValue(-100);
   ASSERT_EQ((unsigned int )  0, progress.getPercentage());
}
 
TEST(ProgressStateTest,  valueEqualTargetIsHundredPercent)
{
   ProgressState progress(200);
   progress.setValue(200);
   ASSERT_EQ((unsigned int ) 100,  progress.getPercentage());
}

This looks like a pretty good start, right?  Now lets run the tests and collect the statistics in Hudson.  To do this we need to add a build step to our Hudson job.

The first three lines of the command simply execute the build.  The command on line 4 executes the binary test application we have built, and outputs the test result summary to a junit format XML file.

The final two commands are where the magic is.  This executes the gcovr script, a handy python script that converts the gcov output to a Cobertura-style XML file.

Then we have to tell hudson to search the build workspace for the junit and coverage xml files as a post-build action.  Now when we run the build we get nice overview charts trending out unit test results and code coverage.

Then when we drill down into the specific source file we can see quite clearly that we have missed a test scenario.

Links

Hudson Continuous Integration Server:

http://hudson-ci.org/

All the source code and makefiles are available publicly on my github account:

http://github.com/meekrosoft/coverage

William E. Hart’s Blog post on gcovr:

http://wehart.blogspot.com/2009/07/summarizing-gcov-coverage-statistics.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值