迭代进行期间或者结束后,在我们的测试日报或者测试报告中需要体现缺陷详细情况,甚至大家工作效率情况。本文就讨论下如何通过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对接:缺陷分析和任务分析的更多相关文章

  1. (五)Jira Api对接:修改任务状态

    项目迭代结束后我们需要把sprint下面的story.task任务状态修改到结束状态,如果手动修改会花费不少时间,本文就介绍如何通过jira api自动修改任务状态,提高工作效率. 一.查看任务工作流 ...

  2. JIRA API 对接

    系统要跟JIRA对接,将本系统数据发送给jira. 开始一头雾水怎么让数据传过去已什么形式存在,是存数据库呢还是怎么显示呢.研究半天发现其实只要将原数据作为json数据提供给jira接口,jira接口 ...

  3. jira以及jira API简单介绍

    最近需要预言:是否可以通过jira API实现用例管理,对jira的应用.API.扩展等进行了一定的了解. Jira介绍: jira是目前比较流行的基于Java架构的管理系统(Atlassian公司支 ...

  4. java 日志体系(四)log4j 源码分析

    java 日志体系(四)log4j 源码分析 logback.log4j2.jul 都是在 log4j 的基础上扩展的,其实现的逻辑都差不多,下面以 log4j 为例剖析一下日志框架的基本组件. 一. ...

  5. 获取使用GitHub api和Jira api Authentication的方法

    近段时间在搭建我司的用例管理平台,有如下需求: 1.需要根据项目--版本--轮次的形式来管理项目用例,用例统一保存在git工程. 2.执行用例时,如果用例执行失败,可以通过平台在Jira上提bug. ...

  6. Java阻塞队列四组API介绍

    Java阻塞队列四组API介绍 通过前面几篇文章的学习,我们已经知道了Java中的队列分为阻塞队列和非阻塞队列以及常用的七个阻塞队列.如下图: 本文来源:凯哥Java(kaigejava)讲解Java ...

  7. 记一次 .NET 某纺织工厂 MES系统 API 挂死分析

    一:背景 1. 讲故事 这个月中旬,有位朋友加我wx求助他的程序线程占有率很高,寻求如何解决,截图如下: 说实话,和不同行业的程序员聊天还是蛮有意思的,广交朋友,也能扩大自己的圈子,朋友说他因为这个b ...

  8. Web自动化框架之五一套完整demo的点点滴滴(excel功能案例参数化+业务功能分层设计+mysql数据存储封装+截图+日志+测试报告+对接缺陷管理系统+自动编译部署环境+自动验证false、error案例)

    标题很大,想说的很多,不知道从那开始~~直接步入正题吧 个人也是由于公司的人员的现状和项目的特殊情况,今年年中后开始折腾web自动化这块:整这个原因很简单,就是想能让自己偷点懒.也让减轻一点同事的苦力 ...

  9. MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析

    文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...

随机推荐

  1. 杨辉三角的实现(Java)

    杨辉三角的实现 一.什么是杨辉三角 杨辉三角是二项式系数在三角形中的一种几何排列.每个数等于它上方两数之和.每行数字左右对称,由1开始逐渐变大.第n行的数字有n项.前n行共[(1+n)n]/2 个数. ...

  2. PTA 二叉树的层次遍历

    6-6 二叉树的层次遍历 (6 分)   本题要求实现给定的二叉树的层次遍历. 函数接口定义: void Levelorder(BiTree T); T是二叉树树根指针,Levelorder函数输出给 ...

  3. 都在讲Redis主从复制原理,我来讲实践总结

    摘要:本文将演示主从复制如何配置.实现以及实现原理,Redis主从复制三大策略,全量复制.部分复制和立即复制. 本文分享自华为云社区<Redis主从复制实践总结>,原文作者:A梦多啦A . ...

  4. 2021年的UWP(6)——长生命周期Desktop Extension向UWP的反向通知

    上一篇我们讨论了UWP和Desktop Extension间的双向通讯,适用于Desktop Extension中存在用户交互的场景.本篇我们讨论最后一种情况,与前者不同的是,Desktop Exte ...

  5. Android Studio 之 EditText

    EditText 简介 •简介 EditText是一个非常重要的组件,可以说它是用户和Android应用进行数据传输窗户: 有了它就等于有了一扇和Android应用传输的门,通过它用户可以把数据传给A ...

  6. vue中的.sync修饰符用法

    在项目中接触到父组件传值给子组件的时候,想在子组件改变父组件传的值.(比如用于弹窗关闭) 但是正常来说,vue2是不允许子组件直接改父组件传进去的值的. 所以我们需要在子组件内定义自定义事件,通知父组 ...

  7. 梳理一下最近准备蓝桥杯时学习DP问题的想法

    学习时间不长,记录的只是学习过程的思路和想法,不能保证正确,代码可以在acwing上AC. 01背包问题: 1.首先是简单的01背包问题 2.先确定状态,f[i][j]表示有第i件物品,时间为j的最大 ...

  8. Jenkins 实现Gitlab事件自动触发Jenkins构建及钉钉消息推送

    实现Gitlab事件自动触发Jenkins构建及钉钉消息推送 实践环境 GitLab Community Edition 12.6.4 Jenkins 2.284 Post build task 1. ...

  9. lustre文件系统环境搭建及测试

    目录 1.节点角色 2.硬件配置 3.软件版本 4.安装软件包 4.1.安装 e2fsprogs 相关包 4.2.安装 kernel 相关包 4.3.客户端安装 4.4.服务器端安装 4.5.配置 5 ...

  10. Mybatis的多表操作

    1.Mybatis多表查询 1.1 一对一查询 1.1.1 一对一查询的模型MapperScannerConfigurer 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一 ...