【nodejs】SWQA平台缺陷模块数据处理
来源:互联网 发布:php框架学习 编辑:程序博客网 时间:2024/05/03 02:28
最近重构数据平台的BUG模块,由于不熟悉,对于一些数据的处理折腾了一小段时间
数据平台的BUG模块主要是从jira平台中请求获取数据,接口文档参考jira的官方文档:
https://docs.atlassian.com/jira/REST/cloud/#api/2/search-search
缺陷状态及类型
- 新增缺陷
缺陷类型(bug、bug-上版本漏测、bug-与需求不符、bug-未自测、bug-需求未更新、tracking)
缺陷严重程度(致命、严重、一般、次要)
- 关闭缺陷
缺陷关闭类型(不能复现、局限性、已解决、无效bug、未处理、设计如此、重复问题)
打回缺陷
遗留缺陷
缺陷类型(bug、bug-上版本漏测、bug-与需求不符、bug-未自测、bug-需求未更新、tracking)
缺陷严重程度(致命、严重、一般、次要)
缺陷状态(新建、重新打开、测试中、开发中、待挂起、被拒绝)
缺陷优先级(Highest、High、Medium、Low、Lowest)
出现频率(总是、无法重现、有时、没有试验、随机)
缺陷模块
缺陷经办人
以上为需要统计的缺陷的状态和相关的数据,缺陷的类型和状态梳理OK后,研究一下请求的语句
请求的语句
使用的url为 /rest/api/2/search
method:get
请求参数为 sql 语句
关于请求不同类型的BUG,如果不分项目,一次性的全部请求后再次解析,目前的BUG数量为差不多1w条,而且这个数值是增长的趋势,故不宜将所有数据获取然后解析,因此分开四种状态,用不同的sql条件去获取BUG
PS:这里说明一下,原本因为打回和关闭缺陷在原先Jira平台中并没有默认的字段,将配置了“缺陷打回时间”、“缺陷关闭时间”和“缺陷关闭类型”等字段后,即可进行搜索,避免了原来的得到新增和遗留问题后计算获得关闭缺陷的无奈之举
新增、关闭、打回和遗留缺陷分别进行查询,因为jira平台中部分缺陷是不需要进行计算和查询,故查询时只进行了部分项目的查询,将每个sql语句进行了封装
var sqlArr = function (DateStart,DateLast,projectApp) { var param = { sqlinfo: [ { type:"new", sql:newbugSql(DateStart,DateLast,projectApp) }, { type:"close", sql:closebugSql(DateStart,DateLast,projectApp) }, { type:"reopen", sql:reopenbugSql(DateStart,DateLast,projectApp) }, { type:"legacy", sql:legacybugSql(projectApp) } ], } return param;}
数据解析
现在看一下请求接口获得的数据
比如现在获取的是某一个项目某一天创建的缺陷,请求jira后响应的数据为:
{ expand: 'schema,names', startAt: 0, maxResults: 1000, total: 8, issues: [ { expand: 'operations,versionedRepresentations,editmeta,changelog,renderedFields', id: '115562', self: 'https://jira.xxxx.com/rest/api/2/issue/115562', key: 'CARE-2126', fields: [Object] }, { expand: 'operations,versionedRepresentations,editmeta,changelog,renderedFields', id: '115449', self: 'https://jira.xxxx.com/rest/api/2/issue/115449', key: 'CARE-2122', fields: [Object] }, { expand: 'operations,versionedRepresentations,editmeta,changelog,renderedFields', id: '115359', self: 'https://jira.xxxx.com/rest/api/2/issue/115359', key: 'CARE-2119', fields: [Object] } ] }
现在解析其中的issues
中一个数据,得到的数据:
{ expand: 'operations,versionedRepresentations,editmeta,changelog,renderedFields', id: '107673', self: 'https://jira.xxxx.com/rest/api/2/issue/107673', key: 'REM-1169', fields: { fixVersions: [], customfield_11200: null, resolution: null, customfield_10509: null, lastViewed: null, priority: [Object], customfield_10100: null, labels: [Object], customfield_10456: '功能缺陷,并没有实行上面模块的更新', customfield_10457: null, aggregatetimeoriginalestimate: null, timeestimate: null, versions: [Object], issuelinks: [Object], assignee: [Object], status: [Object], components: [Object], customfield_10601: null, customfield_10602: '2017-02-21T12:12:00.000+0800', customfield_10448: null, customfield_10603: null, aggregatetimeestimate: null, creator: [Object], subtasks: [], reporter: [Object], customfield_10440: null, aggregateprogress: [Object], customfield_11006: 'win7 64 中文专业,Chrome56.0.2924.87', customfield_10434: null, customfield_10435: null, customfield_11007: [Object], customfield_10436: null, customfield_10315: null, customfield_11008: [Object], votes: [Object], issuetype: [Object], timespent: null, project: [Object], customfield_11000: null, customfield_11117: '无', workratio: -1, watches: [Object], created: '2017-02-21T12:12:56.000+0800', customfield_10419: null, updated: '2017-02-28T15:16:28.000+0800', timeoriginalestimate: null, description: '管理员设置:修改管理员名称后,学校信息列表中的管理员名称不会实时刷新', customfield_10010: null, customfield_10011: null, customfield_11100: null, customfield_11101: [Object], customfield_11102: [Object], customfield_10404: [Object], customfield_10009: '0|i0eaq8:', customfield_10409: '[3788554] 功能缺陷,都已修复咯', summary: '页面刷新:两个不会实时刷新的问题', customfield_11213: null, customfield_10004: null, customfield_11214: null, customfield_10511: null, customfield_11204: null, customfield_11205: null, environment: null, customfield_11206: null, customfield_10514: null, duedate: null, customfield_10517: null } },
根据解析的数据,将需要的信息组合成对象:
var bugdata = { thedate:collectdate, type:"", projectgroup:"", project:item.fields.project.name, //缺项所在项目名称 abb:item.fields.watches.self.split("/")[7], //缺陷编号缩写 creator:item.fields.creator.displayName, //缺陷创建者 createdtime:item.fields.created, //缺陷创建时间 assignee:item.fields.assignee.displayName, //缺陷经办人 affectversions:item.fields.versions[0].name, //缺陷影响版本 fixversions:item.fields.fixVersions[0].name, //缺陷解决版本 status:item.fields.status.name, //缺陷状态 statusCategory:item.fields.status.statusCategory.name, //状态类别 testplatform:item.fields.status.customfield_11006, //测试平台 resolution:item.fields.resolution.name, //解决结果 components:item.fields.components[0].name, //缺陷所属软件模块 labels:item.fields.customfield_11004.value, //缺陷标签 bugtype:item.fields.labels, //缺陷类型 closetype:item.fields.customfield_11007.value, //缺陷关闭类型 severity:item.fields.customfield_11008.value, //缺陷严重程度 priority:item.fields.priority.name, //缺陷优先级 frequency:item.fields.customfield_10413.value, //缺陷出现频率 closeddate:item.fields.customfield_11210, //缺陷关闭时间 reopendate:item.fields.customfield_11211, //缺陷打回时间 }
当然,在处理数据时,发现有些缺陷的某些数据可能是null,故需要进行判断后进行处理
写入数据库
现在的机制是,每天早上7点10分从数据库中获取昨天一天的数据,发现每天的遗留BUG数据约为1000条,3个月即可达到10w的数量级,如果已写在数据库中的遗留BUG只进行Update处理,那么一个遗留BUG的状态、优先级和经办人等信息保存相对比较困难,故不采用这样的方式
由于仅仅是遗留的问题数量级比较大,故将遗留问题在数据库中存为一个表,另外三种状态存为另外一个表中
读取数据库
因为前段不同的模块需要展示不同维度的BUG数据,而且各个项目还需要每个开发的各个维度的BUG数据的情况,故如何处理数据并且将什么数据传给前端
在读取数据库的数据时,如果没需要一个维度的数据就进行一次查询,这样对于数据库的请求次数较为频繁。故使用LEFT JOIN
的方式将查询表进行拼接
如这样的数据库查询语句:
SELECT a.projectgroup,a.project,IFNULL(a.legacy_all,0) as legacy_all,IFNULL(b.legacy_status_build,0) as legacy_status_build,IFNULL(c.legacy_status_reopen,0) as legacy_status_reopen from (SELECT projectgroup, project,count(*)as legacy_all from dataplatform_bugdata_legacy_org where thedate = '2017-03-13' and project = 'SR' group by projectgroup,project)a LEFT JOIN(SELECT project, count(*) as legacy_status_build from dataplatform_bugdata_legacy_org where thedate = '2017-03-13' and project = 'SR' and statuss='新建' group by project,statuss)b ON b.project = b.project LEFT JOIN(SELECT project, count(*) as legacy_status_reopen from dataplatform_bugdata_legacy_org where thedate = '2017-03-13' and project = 'SR' and statuss='重新打开' group by project,statuss)c ON c.project = c.project
查询的表为:
程序请求获取的数据格式为:
RowDataPacket { projectgroup: '项目组一', project: 'SR', legacy_all: 86, legacy_status_build: 54, legacy_status_reopen: 6, legacy_status_testing: 20, legacy_status_develop: 0, legacy_status_suspend: 6, legacy_status_reject: 0, legacy_severity_A: 2, legacy_severity_B: 10, legacy_severity_C: 65, legacy_severity_D: 0 }
这样json left
的方式进行表拼接有个问题,目前当个查询的时长为0.001s的级别,但是如果数据库的数据量较大时,这样的方式查询耗时较大,数据库每个表在一个时刻点只处理一个事件查询,这样会造成堵塞部分查询超时失败
开始想着怎么把这些数据拼凑在一起直接传给前端,故使用Map对数据进行组合
/** * 按照map键值对组合数据 * @param bugDBsql * @param callback */var bugdata = function (bugDBsql,callback) { operateDB.operateDB(bugDBsql,(err,data)=>{ var bugmap = new Map(); for(var item of data){ if(bugmap.get(item.project)==null){ bugmap.set(item.project,[]) bugmap.get(item.project).push(item); }else{ bugmap.get(item.project).push(item); } } callback(bugmap); })}
此时数据格式为:
{ '项目一' => [ RowDataPacket { projectgroup: '项目组一', project: '项目一', legacy_all: 76, legacy_status_build: 10, legacy_status_reopen: 8, legacy_status_testing: 22, legacy_status_develop: 3, legacy_status_suspend: 31, legacy_status_reject: 2, legacy_severity_A: 0, legacy_severity_B: 9, legacy_severity_C: 52, legacy_severity_D: 5 } ], '项目二' => [ RowDataPacket { projectgroup: '项目组二', project: '项目二', legacy_all: 26, legacy_status_build: 20, legacy_status_reopen: 0, legacy_status_testing: 5, legacy_status_develop: 1, legacy_status_suspend: 0, legacy_status_reject: 0, legacy_severity_A: 0, legacy_severity_B: 2, legacy_severity_C: 5, legacy_severity_D: 0 } ], '项目三' => [ RowDataPacket { projectgroup: '项目组三', project: '项目三', legacy_all: 62, legacy_status_build: 27, legacy_status_reopen: 9, legacy_status_testing: 8, legacy_status_develop: 6, legacy_status_suspend: 12, legacy_status_reject: 0, legacy_severity_A: 2, legacy_severity_B: 8, legacy_severity_C: 16, legacy_severity_D: 0 } ], legacy_severity_D: 15 } ], '项目四' => [ RowDataPacket { projectgroup: '项目组四', project: '项目四', legacy_all: 86, legacy_status_build: 54, legacy_status_reopen: 6, legacy_status_testing: 20, legacy_status_develop: 0, legacy_status_suspend: 6, legacy_status_reject: 0, legacy_severity_A: 2, legacy_severity_B: 10, legacy_severity_C: 65, legacy_severity_D: 0 } ], '项目五' => [ RowDataPacket { projectgroup: '项目组五', project: '项目五', legacy_all: 19, legacy_status_build: 7, legacy_status_reopen: 1, legacy_status_testing: 5, legacy_status_develop: 0, legacy_status_suspend: 6, legacy_status_reject: 0, legacy_severity_A: 0, legacy_severity_B: 6, legacy_severity_C: 12, legacy_severity_D: 0 } ] }
感觉这个数据已经完整的组成传给了前端,但是问题来了,这样的数据格式对于前端真的是OK的么?
开始想着的是需要哪个数据直接这样的方式获取:
data.get('item.project').legacy_all
但是问题来了,这个是分为新增、关闭、打回和遗留四个模块,前端数据处理也比较麻烦,而且前端的数据的格式应该是这样的(前期没有确认前端的数据什么方式比较好,这个坑了)
其实给前端的数据格式以数组的方式即可
好吧,这个时候将数据处理成相应的格式
解决的几个比较low的数据处理的问题
- 对象中增加一组键值
var a = { projectgroup: '项目组二', project: '项目二', reopen_all: 1 }a["abc"] = 1;console.log(a)
- 多个回调数据怎么整合处理
使用async.series的方式进行 done(error,null)
进行组合
- 数据组合
在数据组合过程中没有母表,如果创建一个表的话有一大串的数据量,因为只要该项目存在即有遗留的BUG,故将遗留问题这个做为基表,将其他数据加入其中
for(var item_newbug of data.newbug){ for(var item_legacybug_last of data.legacybug_last){ if(item_legacybug_last.project == item_newbug.project){ item_legacybug_last["new_all"] = item_newbug.new_all; item_legacybug_last["new_type_bug"] = item_newbug.new_type_bug; item_legacybug_last["new_type_tracking"] = item_newbug.new_type_tracking; item_legacybug_last["new_severity_A"] = item_newbug.new_severity_A; item_legacybug_last["new_severity_B"] = item_newbug.new_severity_B; item_legacybug_last["new_severity_C"] = item_newbug.new_severity_C; item_legacybug_last["new_severity_D"] = item_newbug.new_severity_D; } } }
如果不存在新增问题这个选项时,将该项目所有的新增对象置为0
if(item_legacybug_last.new_all==null){ item_legacybug_last["new_all"] = 0; item_legacybug_last["new_type_bug"] = 0; item_legacybug_last["new_type_tracking"] = 0; item_legacybug_last["new_severity_A"] = 0; item_legacybug_last["new_severity_B"] = 0; item_legacybug_last["new_severity_C"] = 0; item_legacybug_last["new_severity_D"] = 0; }
这样就按照既定的格式完成了数据获取
- 【nodejs】SWQA平台缺陷模块数据处理
- 跨平台模块tagg2,让nodejs多线程支持
- nodejs转json数据处理
- Nodejs 模块
- nodejs模块
- Nodejs 模块
- nodejs-模块
- NodeJS-模块
- NodeJS模块
- nodejs 模块
- nodejs模块
- Nodejs 模块
- Mantis缺陷管理平台
- GNU Radiuo 数据处理模块
- Python-pandas模块数据处理
- 缺陷模块报告的构成
- nodejs 模块与es6模块
- nodejs模块之fs模块
- java几种排序
- 【程序30】 题目:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。
- HttpURLConnection 遇到connect()或者getOutputStream()卡死的问题
- go应用发布从python的fabic转到shell的expect
- android 5.0 新控件 NavigationView 和 SnackBar
- 【nodejs】SWQA平台缺陷模块数据处理
- 剑指Offer面试题18树的子结构(递归),面试题19二叉树的镜像(递归和非递归用栈)
- Android打包apk提示Error: Expected resource of type id [ResourceType]解决办法
- 安卓的基本的动画介绍
- 带有头结点的双向链表
- js学习笔记
- Hook实现Android 微信,陌陌 ,探探位置模拟
- java-IP处理,路径工具
- websocket之参数传递和依赖注入