(四)Jira Api对接:缺陷分析和任务分析
迭代进行期间或者结束后,在我们的测试日报或者测试报告中需要体现缺陷详细情况,甚至大家工作效率情况。本文就讨论下如何通过jira api获取缺陷信息并进行分析,同时获取需求子任务情况来了解测试和开发的工时。
具体代码如下
//定义数据对象
@Data
public class ReportData { String name; int bugNum; int taskNum; double taskTime; String bugTate;
}
/**
* 获取sprint下的开发任务、测试任务以及缺陷
*
* @param springId
* @return
*/
public static Map<String, Map<String, ReportData>> getReportData(String springId) { Map<String, Map<String, ReportData>> result = new HashMap<>();
//缺陷比较多时我们进行分页查询,默认一页150条数据
JSONObject jsonObject = getIssueKey(0, springId);
if (!JSONNull.getInstance().equals(jsonObject)) { //解析查询的数据
Map<String, ReportData> testerData = new HashMap<>();//测试任务
Map<String, ReportData> developData = new HashMap<>();//开发任务
Map<String, ReportData> bugDetail = new HashMap<>();//缺陷等级
Map<String, ReportData> bugReason = new HashMap<>();//缺陷原因
//解析数据
result = getReportData(jsonObject, testerData, developData, bugDetail, bugReason);
//获取接口返回的缺陷总数
int total = jsonObject.getInt("total");
logger.info("spring上共有story" + total + "个");
if (total > 150) {
//如果大于150则进行分页查询
int page = total / 150;
if (total % 150 > 0) {
page = page + 1;//总页码
}
logger.info("spring上共有story" + page + "页");
for (int pageIndex = 1; pageIndex < page; pageIndex++) { //分页获取数据
JSONObject object = getIssueKey(pageIndex * 150, springId);
if (!JSONNull.getInstance().equals(object)) { //解析数据
result = getReportData(object, result.get("testerGeneral"), result.get("developGeneral"), result.get("bugDetail"), result.get("bugReason"));
}
}
}
}
return result;
}
/**
* 获取spring下的issue
*
* @param startAt
* @param springId
* @return
*/
private static JSONObject getIssueKey(int startAt, String springId) {
//调用jira api接口获取sprint下所有issue
HttpClientResponse issueResponse = httpClient("get", "http://you jira address:port/rest/agile/1.0/sprint/" + springId + "/issue?maxResults=150&startAt=" + startAt, "");
if (issueResponse != null && "200".equals(issueResponse.getStateCode())
&& issueResponse.getResponseBody() != null) {
//直接返回查询结果
JSONObject jsonObject = JSONObject.fromObject(issueResponse.getResponseBody().toString());
return jsonObject;
} return null;
} /**
* 解析数据 分别解析出测试人员情况,开发人员情况,缺陷等级概况以及缺陷原因概况
*
* @param jsonObject
* @param testerData
* @param developData
* @param bugDetail
* @param bugReason
* @return
*/
private static Map<String, Map<String, ReportData>> getReportData(JSONObject jsonObject, Map<String, ReportData> testerData, Map<String, ReportData> developData, Map<String, ReportData> bugDetail, Map<String, ReportData> bugReason) { Map<String, Map<String, ReportData>> result = new HashMap<>();
JSONArray issueArray = jsonObject.getJSONArray("issues");
if (issueArray != null && issueArray.size() > 0) {
for (int i = 0; i < issueArray.size(); i++) { JSONObject issueObject = issueArray.getJSONObject(i);
JSONObject fields = issueObject.getJSONObject("fields");
if (!JSONNull.getInstance().equals(fields)) {
//获取issuetype
JSONObject issuetype = fields.getJSONObject("issuetype");
if (!JSONNull.getInstance().equals(issuetype)) {
//获取issue 类别
String issuetypeName = issuetype.getString("name");
//获取经办人信息
JSONObject assignee = fields.getJSONObject("assignee");
if (!JSONNull.getInstance().equals(assignee)) {
//获取经办人花名
String displayName = assignee.getString("displayName");
//获取完成任务的预估时间的信息,这个字段是自定义字段
double originalEstimate = 0;
JSONObject timetracking = fields.getJSONObject("timetracking");
if (!JSONNull.getInstance().equals(timetracking) && timetracking.size() > 0) {
//获取预估时间
originalEstimate = timetracking.getInt("originalEstimateSeconds") / 3600;
}
//根据任务类别进行不同的处理
switch (issuetypeName) {
case "Story"://需求
break;
case "SubTask"://开发子任务
setReportData(developData, displayName, originalEstimate, false);
break;
case "测试子任务":测试子任务
setReportData(testerData, displayName, originalEstimate, false);
break;
case "缺陷":
//获取解决结果
JSONObject resolution = fields.getJSONObject("resolution");
if (!JSONNull.getInstance().equals(resolution)) {
//过滤掉被否决的bug
if ("被否决".equals(resolution.getString("name"))) {
break;
}
}
setReportData(developData, displayName, 0, true);
//获取报告人信息
JSONObject reporter = fields.getJSONObject("reporter");
if (!JSONNull.getInstance().equals(reporter)) {
//获取报告人花名
String reporterName = reporter.getString("displayName");
setReportData(testerData, reporterName, 0, true);
}
//bug等级进行分类
JSONObject priority = fields.getJSONObject("priority");
setReportData(bugDetail, priority, "name");
//bug原因进行分类
JSONObject reason = fields.getJSONObject("customfield_11522");
setReportData(bugReason, reason, "value");
default:
break;
}
}
}
}
}
} result.put("testerGeneral", testerData);
result.put("developGeneral", developData);
result.put("bugDetail", bugDetail);
result.put("bugReason", bugReason);
return result;
}
/**
* 统一设置报告信息
*
* @param reportDataMap
* @param key
* @param originalEstimate
* @param isBug
*/
private static void setReportData(Map<String, ReportData> reportDataMap, String key, double originalEstimate, boolean isBug) { DecimalFormat decimalFormat = new DecimalFormat("0.00");
if (reportDataMap.containsKey(key)) {
//如果包含key
ReportData temp = reportDataMap.get(key);
if (originalEstimate != 0) {
//设置任务时间,以小时计算
temp.setTaskTime(temp.getTaskTime() + originalEstimate);
}
if (isBug) {
//缺陷数量+1
temp.setBugNum(temp.getBugNum() + 1);
} else {
//任务数量+1
temp.setTaskNum(temp.getTaskNum() + 1);
}
//设置缺陷率
String formatNum = decimalFormat
.format((float) temp.getBugNum()
/ (temp.getTaskTime() == 0 ? 1 : temp.getTaskTime()) * 100);
temp.setBugTate(formatNum + "%");
} else {
ReportData reportData = new ReportData();
if (originalEstimate != 0) {
//设置任务时间,以小时计算
reportData.setTaskTime(originalEstimate);
}
if (isBug) {
//缺陷数量+1
reportData.setBugNum(1);
} else {
//任务数量+1
reportData.setTaskNum(1);
}
//设置缺陷率
String formatNum = decimalFormat
.format((float) reportData.getBugNum()
/ (reportData.getTaskTime() == 0 ? 1 : reportData.getTaskTime()) * 100);
reportData.setBugTate(formatNum + "%");
reportData.setName(key);
reportDataMap.put(key, reportData);
}
} /**
* 统一设置报告信息
*
* @param dataMap
* @param jsonObject
* @param key
*/
private static void setReportData(Map<String, ReportData> dataMap, JSONObject jsonObject, String key) { if (!JSONNull.getInstance().equals(jsonObject)) {
//获取key值
String priorityName = jsonObject.getString(key);
if (dataMap.containsKey(priorityName)) {
//数量+1
ReportData reportData = dataMap.get(priorityName);
reportData.setBugNum(reportData.getBugNum() + 1);
} else {
//数量+1
ReportData reportData = new ReportData();
reportData.setBugNum(1);
reportData.setName(priorityName);
dataMap.put(priorityName, reportData);
}
}
}
//getReportData(String sprintId) 方法返回结果示例,按照Map读取成自己的格式就可以了
{
bugReason={
功能错误=ReportData(name=功能错误,
bugNum=3,
taskNum=0,
taskTime=0.0,
bugTate=null),
需求问题=ReportData(name=需求问题,
bugNum=1,
taskNum=0,
taskTime=0.0,
bugTate=null)
},
developGeneral={
桑落=ReportData(name=桑落,
bugNum=3,
taskNum=7,
taskTime=28.0,
bugTate=10.71%),
白衣=ReportData(name=白衣,
bugNum=0,
taskNum=8,
taskTime=18.0,
bugTate=0.00%),
清远=ReportData(name=清远,
bugNum=1,
taskNum=0,
taskTime=0.0,
bugTate=100.00%)
},
testerGeneral={
黄台=ReportData(name=黄台,
bugNum=4,
taskNum=3,
taskTime=24.0,
bugTate=16.67%)
},
bugDetail={
Medium=ReportData(name=Medium,
bugNum=4,
taskNum=0,
taskTime=0.0,
bugTate=null)
}
}
//对结果优化后以图标显示如下图
更多文章请关注公众号
(四)Jira Api对接:缺陷分析和任务分析的更多相关文章
- (五)Jira Api对接:修改任务状态
项目迭代结束后我们需要把sprint下面的story.task任务状态修改到结束状态,如果手动修改会花费不少时间,本文就介绍如何通过jira api自动修改任务状态,提高工作效率. 一.查看任务工作流 ...
- JIRA API 对接
系统要跟JIRA对接,将本系统数据发送给jira. 开始一头雾水怎么让数据传过去已什么形式存在,是存数据库呢还是怎么显示呢.研究半天发现其实只要将原数据作为json数据提供给jira接口,jira接口 ...
- jira以及jira API简单介绍
最近需要预言:是否可以通过jira API实现用例管理,对jira的应用.API.扩展等进行了一定的了解. Jira介绍: jira是目前比较流行的基于Java架构的管理系统(Atlassian公司支 ...
- java 日志体系(四)log4j 源码分析
java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...
- 获取使用GitHub api和Jira api Authentication的方法
近段时间在搭建我司的用例管理平台,有如下需求: 1.需要根据项目--版本--轮次的形式来管理项目用例,用例统一保存在git工程. 2.执行用例时,如果用例执行失败,可以通过平台在Jira上提bug. ...
- Java阻塞队列四组API介绍
Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...
- 记一次 .NET 某纺织工厂 MES系统 API 挂死分析
一:背景 1. 讲故事 这个月中旬,有位朋友加我wx求助他的程序线程占有率很高,寻求如何解决,截图如下: 说实话,和不同行业的程序员聊天还是蛮有意思的,广交朋友,也能扩大自己的圈子,朋友说他因为这个b ...
- Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)
标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
随机推荐
- 杨辉三角的实现(Java)
杨辉三角的实现 一.什么是杨辉三角 杨辉三角是二项式系数在三角形中的一种几何排列.每个数等于它上方两数之和.每行数字左右对称,由1开始逐渐变大.第n行的数字有n项.前n行共[(1+n)n]/2 个数. ...
- PTA 二叉树的层次遍历
6-6 二叉树的层次遍历 (6 分) 本题要求实现给定的二叉树的层次遍历. 函数接口定义: void Levelorder(BiTree T); T是二叉树树根指针,Levelorder函数输出给 ...
- 都在讲Redis主从复制原理,我来讲实践总结
摘要:本文将演示主从复制如何配置.实现以及实现原理,Redis主从复制三大策略,全量复制.部分复制和立即复制. 本文分享自华为云社区<Redis主从复制实践总结>,原文作者:A梦多啦A . ...
- 2021年的UWP(6)——长生命周期Desktop Extension向UWP的反向通知
上一篇我们讨论了UWP和Desktop Extension间的双向通讯,适用于Desktop Extension中存在用户交互的场景.本篇我们讨论最后一种情况,与前者不同的是,Desktop Exte ...
- Android Studio 之 EditText
EditText 简介 •简介 EditText是一个非常重要的组件,可以说它是用户和Android应用进行数据传输窗户: 有了它就等于有了一扇和Android应用传输的门,通过它用户可以把数据传给A ...
- vue中的.sync修饰符用法
在项目中接触到父组件传值给子组件的时候,想在子组件改变父组件传的值.(比如用于弹窗关闭) 但是正常来说,vue2是不允许子组件直接改父组件传进去的值的. 所以我们需要在子组件内定义自定义事件,通知父组 ...
- 梳理一下最近准备蓝桥杯时学习DP问题的想法
学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...
- Jenkins 实现Gitlab事件自动触发Jenkins构建及钉钉消息推送
实现Gitlab事件自动触发Jenkins构建及钉钉消息推送 实践环境 GitLab Community Edition 12.6.4 Jenkins 2.284 Post build task 1. ...
- lustre文件系统环境搭建及测试
目录 1.节点角色 2.硬件配置 3.软件版本 4.安装软件包 4.1.安装 e2fsprogs 相关包 4.2.安装 kernel 相关包 4.3.客户端安装 4.4.服务器端安装 4.5.配置 5 ...
- Mybatis的多表操作
1.Mybatis多表查询 1.1 一对一查询 1.1.1 一对一查询的模型MapperScannerConfigurer 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一 ...