jacoco 覆盖率与 git diff 结合的应用实践

发表于:2018-5-08 17:06  作者:syl7752   来源:51Testing软件测试网采编

字体: | 上一篇 | 下一篇 |我要投稿 | 推荐标签: 软件测试工具 覆盖率测试

  前言
  覆盖率是衡量测试质量的一个指标,但在版本高速迭代的互联网应用中,单纯通过代码覆盖率的数值是无法体现测试实际覆盖的问题,尤其是版本之间的diff,而且研发也并不会仔细的去看每行代码的覆盖.所以有了覆盖率与git diff结合的想法,通过查看功能测试中版本代码变更的部分是否覆盖,更高效的利用覆盖率,保证变更功能被测试覆盖
  覆盖率的收集
  覆盖率使用的jacoco 关于jacoco手工测试生成:
  Android 手工测试代码覆盖率增强版
  根据q博的方式略做了修改,在应用中加了隐藏开关,并在退出应用时统计覆盖率并上传到服务器.这里用的是ftp,虽然有点过时,但还算方便~
  代码很简单,就不贴了.
  class文件的收集
  jacoco的生成需要对应的class文件,所以需要在编译打包时将class文件上传
  dependencies {
      ftpAntTask("org.apache.ant:ant-commons-net:1.8.4") {
          module("commons-net:commons-net:1.4.1") {
              dependencies "oro:oro:2.0.8:jar"
          }
      }
  }
  def remotedir = "Class/"  //ftp目录
  //def hostname = "10.0.100.210"
  def hostname = "10.0.0.243"
  def username = "uftp"
  def password = "111111"
  task uploadFTP << {
      //上传至FTP
      remotedir += innerVersion
      ant {
          taskdef(name: 'ftp',
                  classname: 'org.apache.tools.ant.taskdefs.optional.net.FTP',
                  classpath: configurations.ftpAntTask.asPath)
          ftp(server: hostname,
                  userid: username,
                  password: password,
                  remotedir: remotedir,
                  action: 'mkdir')
          ftp(server: hostname,
                  userid: username,
                  password: password,
                  remotedir: remotedir) {
              fileset(dir: "./build/intermediates/classes") {
              }
          }
      }
  }
  在jenkins上覆盖率报告生成
  首先在job里添加了三个可选参数,用于选择新旧版本以及分支
  构建时进行jacoco文件的合并和报告的生成,并调用我写的java程序改造报告。
  # generate jacoco report
  gradle jacocoMerge --stacktrace
  gradle jacocoTestReport
  # generate final report
  java -jar ~/work/gitdiff.jar -r $OldVersion $NewVersion -j build/reports/jacoco/jacocoTestReport/html -p src/main/java
  cp -r ~/work/.resources build/reports/jacoco/jacocoTestReport/
  在程序中调用git diff, 并对结果进行解析
  public HashMap<String,FileDiff> parseGitDiff()
       {
           HashMap<String,FileDiff> fileMap=new HashMap<String,FileDiff>();
           ArrayList<String> curFile=new ArrayList<String>();
           for (int i = 0; i < diffList.size(); i++) {
               curFile.add(diffList.get(i));
              if((i+1)==diffList.size()||diffList.get(i+1).startsWith(GIT_FLAG))
              {
                  FileDiff diff=new FileDiff(curFile);
                  fileMap.put(diff.getId(), diff);
                  curFile=new ArrayList<String>();
              }
          }
           return fileMap;
       }
  public ArrayList<LineDiff> parseLineDiff(ArrayList<String> files)
      {
          ArrayList<LineDiff> diff=new ArrayList<LineDiff>();
          boolean isStart=false;
          String frontLine="";
          for (int i = 0; i < block.size(); i++) {
              String line=block.get(i);
              if((i+1)<block.size()&&block.get(i+1).startsWith(MINUS_FLAG)&&!isStart)
              {
                  isStart=true;
                  frontLine=block.get(i);
              }
              if(line.startsWith(MINUS_FLAG)&&isStart)
              {
                  LineDiff lineDiff=new LineDiff(frontLine, line,LineDiff.Type.Minus);
                  diff.add(lineDiff);
              }
              if(i>1&&!block.get(i-1).startsWith(MINUS_FLAG)&&!line.startsWith(MINUS_FLAG))
              {
                  frontLine=block.get(i-1);
                  isStart=false;
              }
              if(line.startsWith(PLUS_FLAG))
              {
                  LineDiff lineDiff=new LineDiff(frontLine,line,LineDiff.Type.Plus);
                  diff.add(lineDiff);
              }
          }
          return diff;
      }
  代码写的不太好,能力强的同学可以忽略~
  将git diff提取出来后找到对应覆盖率html并写入.从而产生了一个只有代码变更文件的list
  效果:
  然后更改jacoco原来的prettify.js文件,对变更代码进行标记
  function showDef (defLine) {
      var beginLine = defLine[0].substring(1);
      var between = defLine[1];
      var target = document.getElementsByClassName('linenums')[3];
      var defDom = document.createElement('div');
      var beginDom = target.getElementsByTagName('li')[beginLine - 1];
      with(defDom.style){
        position = 'absolute';
        left = '9px';
        top = beginDom.offsetTop + 16 + 'px';
        backgroundColor = '#0f0';
        opacity = '.3';
        width = '40px';
        height = 15 * between + 'px';
      };
      defDom.id = 'def' + beginLine;
      document.documentElement.appendChild(defDom);
    }
  对变更代码进行跳转
  function showDefLine () {
      var content = window['CONTENT'];
      var def = content.match(/@@(.*[^@@])/g);
      for (var i = def.length - 1; i >= 0; i--) {
        var _def = def[i].replace(/@@/g, '').split(' ');
        showDef(_def[2].split(','));
      };
      var sourceDom = document.getElementsByClassName('linenums')[1];
      sourceDom = sourceDom.getElementsByTagName('span');
      for (var i = sourceDom.length - 1; i >= 0; i--) {
        if(sourceDom[i].innerHTML === '@@'){
          sourceDom[i].parentNode.onclick = function () {
            document.body.scrollTop = document.getElementById('def' + this.getElementsByTagName('span')[9].innerHTML).offsetTop - 100;
          }
        }
      };
    }
  修改后的效果如下,页面top显示diff代码

  左侧绿色标记diff代码


上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。


评 论

论坛新帖

顶部 底部


建议使用IE 6.0以上浏览器,800×600以上分辨率,法律顾问:上海信义律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2021, 沪ICP备05003035号
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪公网安备 31010102002173号

51Testing官方微信

51Testing官方微博

扫一扫 测试知识全知道