Python统计Jira数据
星安果 人气:0大家好,我是安果!
目前公司使用 Jira 作为项目管理工具,在每一次迭代完成后的复盘会上,我们都需要针对本次迭代的 Bug 进行数据统计,以帮助管理层能更直观的了解研发的代码质量
本篇文章将介绍如何利用统计 Jira 数据,并进行可视化
1. 准备
首先,安装 Python 依赖库
# 安装依赖库 pip3 install jira pip3 install html-table pip3 install pyecharts pip3 install snapshot_selenium
其中
- jira 使用 jsql 语法从在项目中获取需要的数据
- html-table 用于生成一个 HTML 格式的表格数据
- pyecharts 和 snapshot_selenium 用于数据可视化
2. 实战一下
下面我们通过 7 个步骤来实现上面的功能
2-1 登录获取客户端连接对象
from jira import JIRA class JiraObj(object): def __init__(self, bug_style, project_type): """ :param project_name :param sprint: 迭代号码 :param bug_style: BUG状态 """ # Jira首页地址 self.server = 'https://jira.**.team' # Jira登录账号信息 self.basic_auth = ('用户名', '密码') # 创建一个客户端连接信息 self.jiraClinet = JIRA(server=self.server, basic_auth=self.basic_auth)
2-2 根据项目类型获取看板 id
... # 获取boards看板 # 所有看板信息 boards = [(item.id, item.name) for item in self.jiraClinet.boards()] board_id = self.__get_board_id(boards, project_type) print("看板id:", board_id) ... def __get_board_id(self, boards, project_type): """ 获取看板id :param project_type: :return: """ board_id = 1 for item in boards: if (project_type == PROJ_TYPE.Type1 and item[1] == 't1') or ( project_type == PROJ_TYPE.Type2 and item[1] == 't2'): board_id = item[0] break return board_id ..
2-3 根据看板 id 获取迭代 id 及迭代名称
... # 获取项目Sprint,让用户进行选择 sprints = self.jiraClinet.sprints(board_id=board_id) for item in sprints: if str(sprint_no) in item.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 语句,并查询数据
... def get_bug_status_jsql(self, bug_status: BUG_STATUS): """ 通过bug状态,获取jsql :param bug_status: :return: """ status_jsql = '' if bug_status == BUG_STATUS.ALL: status_jsql = ' ' elif bug_status == BUG_STATUS.TO_VERIFY: # 待验证(已解决) status_jsql = ' AND status = 已解决 ' elif bug_status == BUG_STATUS.TO_FIXED: # 待解决(打开、重新打开、处理中) status_jsql = ' AND status in (打开, 重新打开, 处理中) ' elif bug_status == BUG_STATUS.CLOSED: # 关闭 status_jsql = ' AND status = Closed ' elif bug_status == BUG_STATUS.TO_FIXED_CONTAIN_DELAY: # 待解决(打开、重新打开、处理中、延期处理) status_jsql = ' AND status in (打开, 延期处理, 重新打开, 处理中) ' return status_jsql ... jql = f'project = {project_name} and issuetype = 故障 {self.get_bug_status_jsql(self.bug_style)} AND Sprint = {self.sprint_id} ORDER BY priority desc, updated DESC' print(jql) lists = self.get_issue_list(jql) ...
2-5 生成本地 HTML 统计数据
需要注意的是,使用 a 标签组装的链接不能直接跳转,需要针对数据进行二次替换才能正常进行链接跳转
from HTMLTable import ( HTMLTable ) ... def gen_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(""", '"') with open(f"./output/{self.project_name}-bug_{current_time()}.html", 'w', encoding='utf-8') as file: file.write(html) ... # 生成本地文件的数据 output_tuples = tuple([ (item.get("key"), item.get("status"), item.get("priority"), item.get('duty'), item.get('end_type'), f'<a href="{item.get(" rel="external nofollow" url")}" target="_blank">点我查看</a>') for item in lists]) # 生成本地HTML文件 self.gen_html_table(output_tuples) ..
2-6 数据统计
首先,这里按 Bug 责任人进行分组,然后按数目进行降序排列
然后,按 Bug 优先等级进行降序排列
最后,获取每一个端的 Bug 总数
... # 2、统计每个人(按数目) datas_by_count = {} for item in lists: datas_by_count[item.get("duty")] = datas_by_count.get(item.get("duty"), 0) + 1 # 降序排序 datas_by_count = sorted(datas_by_count.items(), key=lambda item: item[1], reverse=True) # print("按Bug总数排序:", datas_by_count) # 3、统计每个人(按优先级) datas_by_priority = {} for item in datas_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=lambda item: (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 绘制成柱状图和饼状图
... def draw_image(self, datas_by_count, datas_by_priority, keys, values): """ 绘制图片 :param values: :param keys: :param datas_by_count: 按bug总数排序结果 :param datas_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] for item in datas_by_count]) bar.add_yaxis(f"BUG总数", [item[1] for item in datas_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] for item in datas_by_priority]) .add_yaxis(self.__get_priority(BUG_PRIORITY.Highest), [item[1][0] for item in datas_by_priority], color='#6aa84f') .add_yaxis(self.__get_priority(BUG_PRIORITY.High), [item[1][1] for item in datas_by_priority], color='#a2c4c9') .add_yaxis(self.__get_priority(BUG_PRIORITY.Medium), [item[1][2] for item in datas_by_priority], color="#ff9900") .add_yaxis(self.__get_priority(BUG_PRIORITY.Low), [item[1][3] for item in datas_by_priority], color="#ea9999") .add_yaxis(self.__get_priority(BUG_PRIORITY.Lowest), [item[1][4] for item in datas_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、根据终端来绘制饼图 if len(keys) > 0 and len(values) > 0: c = ( Pie() .add("", [list(z) for z in zip(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 类型,就能统计出所需要的数据并绘制成图表
加载全部内容