目录1.准备2.实战一下3.总结大家好,我是安果!目前公司使用Jira作为项目管理工具,在每一次迭代完成后的复盘会上,我们都需要针对本次迭代的Bug进行数据统计,以帮助管理层能更直观的了解研发的...
目录
1. 准备2. 实战一下
3. 总结
大家好,我是安果!
目前公司使用 Jira 作为项目管理工具,在每一次迭代完成后的复盘会上,我们都需要针对本次迭代的 Bug 进行数据统计,以帮助管理层能更直观的了解研发的代码质量
本篇文章将介绍如何利用统计 Jira 数据,并进行可视化
1. 准备
首先,安装 python 依赖库
#安装依赖库 pip3installjira pip3installhtml-table pip3installpyecharts pip3installsnapshot_selenium
其中
jira 使用 jsql 语法从在项目中获取需要的数据html-table 用于生成一个 HTML 格式的表格数据
pyecharts 和 snapshot_selenium 用于数据可视化
2. 实战一下
下面我们通过 7 个步骤来实现上面的功能
2-1 登录获取客户端连接对象
fromjiraimportJIRA
classJiraObj(object):
def__init__(self,bug_style,project_type):
"""
:paramproject_name
:paramsprint:迭代号码
:parambug_style:BUG状态
"""
#Jira首页地址
self.server='https://jira.**.team'
#Jira登录账号信息
self.basic_auth=('python用户名','密码')
#创建一个客户端连接信息
self.jiraClinet=JIRA(server=self.server,basic_auth=self.basic_auth)
2-2 根据项目类型获取看板 id
...
#获取boards看板
#所有看板信息
boards=[(item.id,item.name)foriteminself.jiraClinet.boards()]
board_id=self.__get_board_id(boards,project_type)
print("看板id:",board_id)
...
def__get_board_id(self,boards,project_type):
"""
获取看板id
:paramproject_type:
:return:
"""
board_id=1
foriteminboards:
if(project_type==PROJ_TYPE.Type1anditem[1]=='t1')or(
project_type==PROJ_TYPE.Type2anditem[1]=='t2'):
board_id=item[0]
break
returnboard_id
..
2-3 根据看板 id 获取迭代 id 及迭代名称
...
#获取项目Sprint,让用户进行选择
sprints=self.jiraClinet.sprints(board_id=board_id)
foriteminsprints:
ifstr(sprint_no)initem.name:
self.sprint_id=item.id
self.sprint_name=item.name
print(f"选择Sprint,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=已解决'
elifbug_status==BUG_STATUS.TO_FIXED:
#待解决(打开、重新打开、处理中)
status_jsql='ANDstatusin(打开,重新打开,处理中)'
elifbug_status==BUG_STATUS.CLOSED:
#关闭
status_jsql='ANDstatus=Closed'
elifbug_status==BUG_STATUS.TO_FIXED_CONTAIN_DELAY:
#待解决(打开、重新打开、处理中、延期处理)
status_jsql='ANDstatusin(打开,延期处理,重新打开,处理中)'
returnstatus_jsql
...
jql=f'project={project_name}andissuetype=故障{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 标签组装的链接不能直接跳转,需要针对数据进行二次替换才能正常进行链接跳转
fromHTMLTableimport(
HTMLTable
)
...
defgen_html_table(self,datas):
"""
初始化表单样式
:return:
"""
table=HTMLTable(caption=f'实时BUG统计【{self.project_name}】,一共{len(datas)}个')
#表头行
table.append_header_rows((('ID','状态','优先级','责任人','终端','URL'),))
#添加数据
table.append_data_rows(datas)
#设置样式
table.caption.set_style({'font-size':'15px'})
#其他样式设置
...
#替换数据,便于展示href地址
html=table.to_html().replace("<","<").replace(">",">").replace(""",'"')
withopen(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'<ahref="{item.get(" rel="extwww.cppcns.comernal nofollow" url")}"target="_blank">点我查看</a>')foritehttp://www.cppcns.comminlists])
#生成本地HTML文件
self.gen_html_table(output_tuples)
..
2-6 数据统计
首先,这里按 Bug 责任人进行分组,然后按数目进行降序排列
然后,按 Bug 优先等级进行降序排列
最后,获取每一个端的 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("按Bug总数排序:",datas_by_count)
#3、统计每个人(按优先级)
datas_by_priority={}
foritemindatas_by_count:
#责任人
name=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("按Bug优先级排序:",datas_by_priority)
#4、根据终端进行统计分类
keys,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:按bug总数排序结果
:paramdatas_by_priority:按bug优先级排序结果
:return:
"""
#1、按BUG总数排序绘制
bar=(
Bar().set_global_opts(
title_opts=opts.TitleOpts(title=f"{self.project_name}",subtitle=f"{self.sprint_name}")))
bar.add_xaxis([item[0]foritemindatas_by_count])
bar.add_yaxis(f"BUG总数",[item[1]foritemindatas_by_count])
#render会生成本地HTML文件,默认会在当前目录生成render.html文件
#也可以传入路径参数,如bar.render("mycharts.html")
#bar.render(path=f'{sprint_name}-BUG总数.html')
make_snapshot(snapshot,bar.render(),"./output/1.png")
#2、按优先级排序绘制
bar2=(
#Bar(init_opts=opts.InitOpts(theme=ThemeType.INFOGRAPHIC))
Bar()
.add_xaxis([item[0]foritemindatas_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统计Jira数据并可视化的文章就介绍到这了,更多相关Python统计Jira数据内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!










