我们已有CI job把单元测试结果发布到Sonar中,但Sonar的界面,你懂的。我们希望只关注我们部门相关项目的CodeCoverage数据,以及具体不达标项目的模块。
查阅了Sonar的API文档,http://nemo.sonarqube.org/api_documentation。api/resources 可以利用。
例子:
请求:http://sonar.vip.qa.ebay.com/api/resources?resource=Scala&depth=0&metrics=coverage,test_success_density,it_coverage,total-quality&format=json&callback=jQuery19108647494609467685_1419918769346&_=1419918769347
回复:jQuery19108647494609467685_1419918769346([{"id":312828,"key":"Scala","name":"Scala","scope":"PRJ","qualifier":"SVW","date":"2014-12-29T20:31:18-0700","creationDate":"2014-07-25T12:06:48-0700","lname":"Scala","lang":"none","msr":[{"key":"coverage","val":76.0,"frmt_val":"76.0%"},{"key":"total-quality","val":86.6,"frmt_val":"86.6%"}]}]);
通过这个请求,我们就得到相应的覆盖率等数据。
我们只需要用javascript利用jQuery的Ajax调用,分析返回的数据,然后用表格的形式展示出来。
具体的代码很简单:
<!DOCTYPE html> <html> <head> <script src="../javascripts/jquery.js" type="text/javascript"></script> <link href="http://ir.qa.ebaystatic.com/z/mk/q0km4qa2bizklor5ltdsqgthq.css?dataUri=true" type="text/css" rel="stylesheet"></head> <body bgcolor="transparent"> </head> <body> <style> .table th {text-align:center} </style> <div class="span14"> <div id="divother"></div> </div> <script> $(document).ready(function(){ //alert("hi"); populateQualityConfidenceTable(); }); function sortByProperty(property) { //'use strict'; return function (a, b) { var sortStatus = 0; if (a[property] < b[property]) { sortStatus = -1; } else if (a[property] > b[property]) { sortStatus = 1; } return sortStatus; }; } function printTableHeader(val){ var tableheader = ""; if(val.msr[0]!=undefined && val.msr[1]!=undefined){ if((val.lname.replace(/ /g,"") == "Scala") ) { tableheader = '<tr class="table" style="text-align:center"><th colspan="1"><font color="blue"><a id="test" href="#" onclick="openPage(\'http://sonar.vip.qa.ebay.com/dashboard/index/' + val.key + '\');return false;">' + val.lname.replace(/ /g,"") + '</a></font></th><th></th><th colspan="1">' + val.msr[0].frmt_val + '</th><th colspan="1">0.00</th><th colspan="1">0.00</th><th colspan="1">' + val.msr[1].frmt_val + '</th></tr>'; tableheader = tableheader + '<tr><td colspan="7" align="center"><b>' + val.lname.replace(/ /g,"") + ' Sub Components</b></td></tr>'; tableheader = tableheader + '<tr><th>Product</th><th colspan="1">Module</th><th>UT Coverage</th><th>Pass</th><th>FT Coverage</th><th><a id="qc" href="#" onclick="openPage(\'http://docs.codehaus.org/display/SONAR/Total+Quality+Plugin\');return false;">Quality Confidence</a></th></tr>'; }else{ if(val.msr[1].frmt_val.replace(/%/,"")>=85){ tableheader = tableheader + '<tr bgcolor="#dedede"><td><a id="test" href="#" onclick="openPage(\'http://sonar.vip.qa.ebay.com/dashboard/index/' + val.key + '\');return false;">' + val.lname.replace(/ /g,"") + '</a></td><td></td><td>' + val.msr[1].frmt_val + '</td><td>0.00</td><td>0.00</td><td >' + val.msr[0].frmt_val + '</td></tr>'; }else{ tableheader = tableheader + '<tr bgcolor="#dedede"><td><a id="test" href="#" onclick="openPage(\'http://sonar.vip.qa.ebay.com/dashboard/index/' + val.key + '\');return false;">' + val.lname.replace(/ /g,"") + '</a></td><td></td><td bgcolor="red">' + val.msr[1].frmt_val + '</td><td>0.00</td><td>0.00</td><td >' + val.msr[0].frmt_val + '</td></tr>'; } } } return tableheader; } function populateQualityConfidenceTable(){ sonar_baseurl_head = "http://sonar.vip.qa.ebay.com/api/resources?resource="; var sonar_baseurl_tail_withzerodepth = "&depth=0&metrics=coverage,test_success_density,it_coverage,total-quality&format=json"; var sonar_baseurl_tail_withonedepth = "&depth=1&metrics=scoverage,test_success_density,it_coverage,total-quality&format=json"; var metric_scala_coverage = sonar_baseurl_head + "Scala" + sonar_baseurl_tail_withzerodepth; var metric_sub_polyglot_coverage = sonar_baseurl_head + "Scala" + sonar_baseurl_tail_withonedepth; var requestUrl = ""; var modules = 0; //alert(metric_scala_coverage); var table = '<table style="width:100%">'; $.ajax({ url : metric_scala_coverage + "&callback=?", async : false, dataType: 'json', success: function(polyjson) { $.ajax({ url : metric_sub_polyglot_coverage + "&callback=?", async : false, dataType: 'json', success: function(subpolyjson) { polyData = polyjson.concat(subpolyjson.sort(sortByProperty('lname'))); var dataArray = [polyData]; table = table + '<tr><th colspan="1">Product</th><th colspan="1">Module</th><th colspan="1">UT Coverage</th><th colspan="1">Pass</th><th colspan="1">FT Coverage</th><th colspan="1"><a id="qc" href="#" onclick="openPage(\'http://docs.codehaus.org/display/SONAR/Total+Quality+Plugin\');return false;">Quality Confidence</a></th></tr>'; for (var j = 0; j < dataArray.length; j++) { $.each(dataArray[j], function(i, val) { if(val.lname.replace(/ /g,"") == "Scala"){ table = table + printTableHeader(val); } else{ if(val.lname.replace(/ /g,"") == "higgins"){ requestUrl = sonar_baseurl_head + "com.ebay.higgins" + sonar_baseurl_tail_withonedepth; }else if(val.lname.replace(/ /g,"") == "squbs"){ requestUrl = sonar_baseurl_head + "com.ebay.squbs" + sonar_baseurl_tail_withonedepth; }else if(val.lname.replace(/ /g,"") == "rocksqubs"){ requestUrl = sonar_baseurl_head + "com.ebay.rocksqubs" + sonar_baseurl_tail_withonedepth; }else{ requestUrl = sonar_baseurl_head + "com.ebay.squbs.chnlsvc" + sonar_baseurl_tail_withonedepth; } $.ajax({ url : requestUrl + "&callback=?", async : false, dataType: 'json', success: function(json) { scalaData = json//.sort(sortByProperty('lname')); var dataArray = [scalaData]; var subtable = "" for (var k = 0; k < dataArray.length; k++) { $.each(dataArray[k], function(l, val2) { if(parseFloat(val2.msr[1].frmt_val.replace(/%/,""))>=85){ subtable = subtable + '<tr id="'+val2.lname.replace(/ /g,"")+'"><td></td><td><a id="test" href="#" onclick="openPage(\'http://sonar.vip.qa.ebay.com/dashboard/index/' + val2.key + '\');return false;">' + val2.lname.replace(/ /g,"") + '</a></td><td>' + val2.msr[1].frmt_val + '</td><td>0.00</td><td>0.00</td><td >' + val2.msr[0].frmt_val + '</td></tr>'; }else{ subtable = subtable + '<tr bgcolor="yellow" id="'+val2.lname.replace(/ /g,"")+'"><td></td><td><a id="test" href="#" onclick="openPage(\'http://sonar.vip.qa.ebay.com/dashboard/index/' + val2.key + '\');return false;">' + val2.lname.replace(/ /g,"") + '</a></td><td >' + val2.msr[1].frmt_val + '</td><td>0.00</td><td>0.00</td><td >' + val2.msr[0].frmt_val + '</td></tr>'; } }); } var tableheader = printTableHeader(val); table = table + tableheader + subtable; modules = modules + 1; //alert(modules); if(modules==4){ //alert("final"); table = table + '</table>'; var qc = $('<div class="coverageTable"><div id="coverageTable" style="border-color: #4271A5" align="center">' +'<div align="center" id="tabletarget" style="width:99%;overflow: auto;">' + table + '</div></div></div>'); $('#divother').append(qc); } } }); } }); } } }); } }); } </script> </body> </html>
这里需要注意的是,Table的拼凑部分必须放在最里层的ajax回调函数中,否则不能保证先后顺序,会导致表格出现一些错乱。
由于我们的项目是Scala项目, 所以使用了Scoverage来做unit test,所以请求中,用scoverage替换了coverage
相关推荐
该资源提供了sonar webAPI的方式创建用户、删除用户、项目权限赋值等相关脚本实现方式
利用java代码,调用sonar接口,实现在sonar里面创建,更改,用户,组,权限等一系列操作
This is a step-by-step tutorial enriched with practical ... This book is for you if you are a Java developer or a Team Manager familiar with Java and want to ensure the quality of your code using Sonar.
yaml.zip,创建yaml节点的jackson类api(基于snakeyaml)读取和创建yaml节点的jackson类api(基于snakeyaml)。
constraintscala.zip,约束萨拉
目录 1. Sonar安装 2 1.1下载sonar 2 1.2安装sonar 2 2.在maven中配置sonar 2 ...4.1整个sonar报表主要为6部分,如下图为红色数字以标记 4 4.2在Critical中有三种错误提示如下: 6 4.3持续集成曲线图 7
sonar eclipse插件sonarlint,原先的插件已经被启用,这是最新的,如果连接本地sonar服务器,需要在eclipse.ini中配置启动参数,参数为org.sonarlint.eclipse.core/server_url 值为sonar服务器地址,如果不配置默认...
annovention.zip,java注释发现库http://code.google.com/p/annovention/的一个分支,它修复了错误并删除了apache日志依赖性,以保持库的轻量级
sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包sonar汉化包
sonar中文插件1.28,适用于最后一个jdk1.8版本的sonar,sonar-l10n-zh-plugin-1.28.jar
基于coverage.py进行代码覆盖率检查 另外为了进一步解决自动化测试、开发过程的种种问题,我们也对以下工具进行了研究 基于virtualenv进行测试环境隔离的,它的目标很简单:如果你的一台机子中有很多Python项目...
sonar-kotlin Features Integrates detekt for code analysis Default quality profile Detekt way Syntax highlighting Supports SonarQube 6.7.3 and up Supports detekt's yaml config and baseline.xml ...
详解如何调用sonarqube,附带完整api,详细代码直接调用sonar即可(需sonar管理的项目)
使用方法:下载完成后解压文件,里边有“SonarLint.VSIX-5.3.0.41207-2019.vsix”、“SonarLint.VSIX-6.9.0.54300-2022.vsix”,根据自己vs版本选择适配的版本,双击运行即可,按照提示安装完成即可。
Sonarlint是一款强大的代码检测插件,用户可以IDE上实时检测自己的代码问题。本文详细介绍了Eclipse和Idea集成Sonarlint的步骤和使用方法
sonar-gitlab-plugin-4.0.0.jar sonar-l10n-zh-plugin-1.28.jar sonar-pmd-plugin-3.2.0-SNAPSHOT.jar sonar-scanner-cli-4.0.0.1744-linux.zip sonarqube-7.8.zip
声纳网络服务客户端 这是一个使用 Sonar Web API 的示例实现。 Sonar Web API 在下面有一个参考。 请参阅链接以获取 GET 参数和响应数据的示例。
VS2015的sonarlint 插件。 因为这是一个离线的文件,需要安装到visual studio中,怎么操作呢? 也是有办法的,不能直接像普通的exe文件一样双击就可以安装,他需要利用visual studio环境下的vsixinstaller.exe可...
sonar的checkStyle插件,直接下载放到sonar的插件文件夹就可以用了。
UCI的一个数据集Sonar,已经用MATLAB转化为.mat数据文件了,在MATLAB里面可以直接load