当前位置: 首页 > 后端技术 > Python

如何使用Python统计Jira数据并可视化

时间:2023-03-26 13:08:19 Python

目前公司使用Jira作为项目管理工具。在每次迭代后的评审会上,我们需要对本次迭代的bug进行统计,帮助管理层更直观的了解研发的代码质量。本文将介绍如何使用Jira统计数据并将其可视化。1、准备工作首先安装Python依赖库#安装依赖库pip3installjirapip3installhtml-tablepip3installpyechartspip3installsnapshot_selenium其中jira使用jsql语法从项目中获取需要的数据html-table用于生成表格数据inHTML格式,pyecharts和snapshot_selenium用于数据可视化二、实战下面通过7个步骤来实现以上功能2-1登录获取客户端连接对象fromjiraimportJIRAclassJiraObj(object):def__init__(self,bug_style,project_type):""":paramproject_name:paramsprint:iterationnumber:parambug_style:BUGstatus"""#Jira主页地址self.server='https://jira.**.team'#Jira登录账号信息self.basic_auth=('username','password')#创建客户端连接信息self.jiraClinet=JIRA(server=self.server,basic_auth=self.basic_auth)2-2根据项目类型获取kanbanid...#获取看板n#所有看板信息板=[(item.id,item.name)foriteminself.jiraClinet.boards()]board_id=self.__get_board_id(boards,project_type)print("Boardid:",board_id)...def__get_board_id(self,boards,project_type):"""Getboardid:paramproject_type::return:"""board_id=1对于板中的项目:if(project_type==PROJ_TYPE.Type1anditem[1]=='t1')or(project_type==PROJ_TYPE.Type2anditem[1]=='t2'):board_id=item[0]breakreturnboard_id..2-3根据看板id获取迭代id和迭代名称...#获取项目Sprint,让用户选择sprints=self.jiraClinet.sprints(board_id=board_id)foritemin冲刺:ifstr(sprint_no)initem.name:self.sprint_id=item.idself.sprint_name=item.nameprint(f"SelectSprint,id:{self.sprint_id},name:{self.sprint_name}")break...2-4根据项目名称、bug类型、迭代id组成jsql语句,查询数据...defget_bug_status_jsql(self,bug_status:BUG_STATUS):"""通过bug状态获取jsql:parambug_status::return:"""status_jsql=''ifbug_status==BUG_STATUS.ALL:status_jsql=''elifbug_status==BUG_STATUS.TO_VERIFY:#待验证(已解决)status_jsql='ANDstatus=resolved'elifbug_status==BUG_STATUS.TO_FIXED:#待解决(打开,重新打开,处理)status_jsql='ANDstatusin(open,reopen,Processing)'elifbug_status==BUG_STATUS.CLOSED:#关闭status_jsql='ANDstatus=Closed'elifbug_status==BUG_STATUS.TO_FIXED_CONTAIN_DELAY:#待解决(打开、重新打开、处理、延迟处理)status_jsql='ANDstatusin(open,deferred,重新打开,进行中)'返回status_jsql...jql=f'project={project_name}andissuetype=fault{self.get_bug_status_jsql(self.bug_style)}ANDSprint={self.sprint_id}ORDERBYprioritydesc,updatedDESC'print(jql)lists=self.get_issue_list(jql)...2-5生成本地HTML统计数据需要注意的是,用a标签组装的链接不能直接重定向,需要替换两次数据才能normal执行链接跳转fromHTMLTableimport(HTMLTable)...defgen_html_table(self,datas):"""初始化表单样式:return:"""table=HTMLTable(caption=f'实时BUG统计【{self.project_name}],一共{len(datas)}')#表头行table.append_header_rows((('ID','status','priority','负责人','terminal','URL'),))#添加数据table.append_data_rows(datas)#设置样式table.caption.set_style({'font-size':'15px'})#其他样式设置...#替换数据,方便显示href地址html=表。to_html().replace("<","<").replace(">",">").replace(""",'"')与open(f"./output/{self.project_name}-bug_{current_time()}.html",'w',encoding='utf-8')asfile:file.write(html)...#生成本地文件数据output_tuples=tuple([(item.get("key"),item.get("status"),item.get("priority"),item.get('duty'),item.get('end_type'),f'点我查看')foriteminlists])#生成本地HTML文件self.gen_html_table(output_tuples)..2-6数据统计先按bug负责人分组,再按编号降序排序。然后,按错误优先级降序排序。最后,得到每一端的错误总数...#2.统计每个人(按数量)datas_by_count={}foriteminlists:datas_by_count[item.get("duty")]=datas_by_count.get(item.get("duty"),0)+1#降序排序datas_by_count=sorted(datas_by_count.items(),key=lambdaitem:item[1],reverse=True)#print("按错误总数排序:",datas_by_count)#3.统计每个人(按优先级)datas_by_priority={}foritemindatas_by_count:#负责人姓名=item[0]#5个优先级对应的数字counts=self.get_assignee_count(lists,name)datas_by_priority[name]=counts#排序(按优先级和多个条件降序排列)datas_by_priority=sorted(datas_by_priority.items(),key=lambdaitem:(item[1][0],item[1][1],item[1][2],item[1][3]),reverse=True)#print("SortbyBugpriority:",datas_by_priority)#4.根据terminal,values=self.get_end_type_count(lists)...2-7可视化对于以上3组数据,使用pyecharts绘制直方图和饼图...defdraw_image(self,datas_by_count,datas_by_priority,keys,values):"""画图:paramvalues::paramkeys::paramdatas_by_count:按错误总数排序结果:paramdatas_by_priority:按错误优先级排序结果:return:"""#1.按错误总数排序并绘制bar=(Bar().set_global_opts(title_opts=opts.TitleOpts(title=f"{self.project_name}",subtitle=f"{self.sprint_name}")))bar.add_xaxis([item[0]为了它emindatas_by_count])bar.add_yaxis(f"BUG总数",[item[1]foritemindatas_by_count])#render会在本地生成一个html文件,render.html文件会在当前目录生成default#也可以传入path参数,比如bar.render("mycharts.html")#bar.render(path=f'{sprint_name}-BUGtotal.html')make_snapshot(snapshot,bar.render(),"./output/1.png")#2.按优先级绘制bar2=(#Bar(init_opts=opts.InitOpts(theme=ThemeType.INFOGRAPHIC))Bar().add_xaxis([item[0]foritem在datas_by_priority]).add_yaxis(self.__get_priority(BUG_PRIORITY.Highest),[item[1][0]foritemindatas_by_priority],color='#6aa84f').add_yaxis(self.__get_priority(BUG_PRIORITY.High),[item[1][1]foritemindatas_by_priority],color='#a2c4c9').add_yaxis(self.__get_priority(BUG_PRIORITY.Medium),[item[1][2]foritemindatas_by_priority],color="#ff9900").add_yaxis(self.__get_priority(BUG_PRIORITY.Low),[item[1][3]foritemindatas_by_priority],color="#ea9999").add_yaxis(self.__get_priority(BUG_PRIORITY.Lowest)),[item[1][4]foritemindatas_by_priority],color="#980000").set_global_opts(title_opts=opts.TitleOpts(title=f"{self.project_name}",subtitle=f"{self.sprint_name}")))#bar2.render(path=f'{sprint_name}-BUG优先级.html')make_snapshot(snapshot,bar2.render(),"./output/2.png")#3、根据最终绘制饼图iflen(keys)>0andlen(values)>0:c=(Pie().add("",[list(z)forzinzip(keys,values)]).set_global_opts(title_opts=opts.TitleOpts(title="各端BUG分配")).set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}")))make_snapshot(snapshot,c.render(),f"./output/{self.project_name}_end.png")#4.合并两张图片self.concatenate_img(['./output/1.png','./output/2.png'],img_name=f'./output/{self.sprint_name}_bug.png',axis=1)...3。总结通过以上操作,每次只需要输入需要统计的项目类型、迭代版本号、bug类型,就可以统计出需要的数据,并绘制成图表。Python学习资料,包括初学者电子书、教程、源码等,免费分享给大家!想上“Python编程学习圈”,发“J”免费领取