import requests
import json
import xlrd
import os
import datetime
from xlrd import xldate_as_tuple
from xlrd import xldate_as_datetime
'''
自动登录并发布bug到禅道系统中
'''
class Zentao_cli(object):
session = None # 用于实现单例类,避免多次申请sessionID
sid = None
def __init__(self, url, account, password, override=False):
self.url = url
self.account = account # 账号
self.password = password # 密码
self.session_override = override # 是否覆盖原会话
self.pages = {
"sid": "/index.php?m=api&f=getSessionID&t=json", # 获取sid的接口
"login": "/index.php?t=json&m=user&f=login&account={0}&password={1}&sid={2}", # 登录的接口
"upload_image": "/index.php?m=file&f=ajaxUpload&t=html&uid={0}&dir=image",
"get_bug_list_by_product_id": "/index.php?m=bug&f=browse&t=json&productID={0}",
"add_bug": "/index.php?m=bug&f=create&productID={0}&branch=0&extra=moduleID=0"
}
self.s = None
self.sid = None
'''
发生请求并返回结果
'''
def req(self, url):
# 请求并返回结果
web = self.s.get(url)
if web.status_code == 200:
resp = json.loads(web.content)
if resp.get("status") == "success":
return True, resp
else:
return False, resp
'''
登录禅道
'''
def login(self):
if self.s is None:
if not self.session_override and Zentao_cli.session is not None:
self.s = Zentao_cli.session
self.sid = Zentao_cli.sid
else:
# 新建会话
self.s = requests.session()
res, resp = self.req(self.url.rstrip("/") + self.pages["sid"])
if res:
print("获取sessionID成功")
self.sid = json.loads(resp["data"])["sessionID"]
Zentao_cli.sid = self.sid
login_res, login_resp = self.req(
self.url.rstrip("/") + self.pages["login"].format(self.account, self.password, self.sid))
if login_res:
print("登录成功")
Zentao_cli.session = self.s
'''
获取bug列表
'''
def get_bug_list_by_project(self, project_id):
# 根据projectID获取bug列表
req_url = self.url.rstrip("/") + self.pages["get_bug_list_by_product_id"].format(str(project_id))
web = self.s.get(req_url)
if web.status_code == 200:
resp = json.loads(web.content.decode())
for k, v in resp.items():
print(k, v)
'''
上传图片到禅道中
'''
def upload_file(self, local_path, file_name):
req_url = self.url.rstrip("/") + self.pages["upload_image"].format("6142fa2a6ccad")
image_file = {
"localUrl": (None, file_name),
"imgFile": (file_name, open(local_path, "rb"), "image/png")
}
result = self.s.post(req_url, files=image_file)
try:
jpg_url = self.url.rstrip("/") + result.json()["url"]
# 删除已上传的图片
image_file = {}
os.remove(local_path)
print(u"上传图片后的url地址:%s" % jpg_url)
return result.json()["url"]
except Exception as msg:
print(u"返回值不是json格式:%s" % str(msg))
print(result.content)
exit()
return ""
'''
添加bug到禅道系统中
'''
def add_bug(self, params):
req_url = self.url.rstrip("/") + self.pages["add_bug"].format(str(params["product"]))
header = {'Content-Type': "application/x-www-form-urlencoded; charset=utf-8"} # 设置请求头
responses = self.s.post(req_url, headers=header, data=params)
print(responses.content.decode("utf-8"))
'''
从excel中导入Bug到禅道中
'''
def add_bug_from_excel(self, file_path, pic_dir):
data1 = xlrd.open_workbook(file_path)
table = data1.sheets()[0]
tables = []
for row in range(table.nrows):
if row == 0:
continue
bug_id = table.cell_value(row, 0)
title = table.cell_value(row, 1)
if title == '':
break
project = int(table.cell_value(row, 2))
product = int(table.cell_value(row, 3))
bug_type = table.cell_value(row, 4)
severity = int(table.cell_value(row, 5))
primary = int(table.cell_value(row, 6))
assigned_to = table.cell_value(row, 7)
steps = "[步骤]<br/>" + table.cell_value(row, 8) + "<br/>"
result = "[结果]<br/>" + table.cell_value(row, 9) + "<br/>"
result_pic_path = pic_dir + "\\" + str(int(bug_id)) + "\\result\\"
result_pic_html = ''
# 循环上传结果的照片
for root, dirs, files in os.walk(result_pic_path):
for file in files:
if os.path.splitext(file)[1] == '.jpg' or os.path.splitext(file)[1] == '.png':
result_pic_html += "<img src=\"" + self.upload_file(os.path.join(root, file),
str(bug_id) + "结果_" + file) + "\" /><br/>"
if result_pic_html != "":
result += result_pic_html
expect = "[期望]<br/>" + table.cell_value(row, 10) + "<br/>"
# 循环上传期望的照片
expect_pic_path = pic_dir + "\\" + str(int(bug_id)) + "\\expect\\"
expect_pic_html = ''
# 循环上传结果的照片
for root, dirs, files in os.walk(expect_pic_path):
for file in files:
if os.path.splitext(file)[1] == '.jpg' or os.path.splitext(file)[1] == '.png':
expect_pic_html += "<img src=\"" + self.upload_file(os.path.join(root, file),
str(bug_id) + "期望_" + file) + "\" /><br/>"
if expect_pic_html != "":
expect += expect_pic_html
dead_line = table.cell_value(row, 11)
if dead_line != "":
dead_line = xldate_as_datetime(dead_line, 0).strftime('%Y/%m/%d')
keywords = table.cell_value(row, 12)
array = {
"product": product, # int 所属产品 * 必填
"openedBuild": "trunk", # int | trunk 影响版本 * 必填
"branch": "2", # int 分支 / 平台
"module": "0", # int 所属模块
"project": project, # int 所属项目
"assignedTo": assigned_to, # string 指派给
"deadline": dead_line, # date 截止日期 日期格式:YY - mm - dd,如:2019 - 01 - 01
"type": bug_type, # bug类型
"severity": severity, # int 严重程度 取值范围:1 | 2 | 3 | 4
"pri": primary, # int 优先级 取值范围:0 | 1 | 2 | 3 | 4
"keywords": keywords, # string 关键词
"title": title, # 标题
"story": 0, # 需求
"steps": steps + result + expect # string 重现步骤
}
tables.append(array)
# 上传Bug到禅道
self.add_bug(array)
return tables
if __name__ == "__main__":
cli = Zentao_cli("http://192.168.1.27:8081", "weiyongli", "123456789")
cli.login()
'''
上传的图片需为jpg格式
图片路径规则:
----图片文件夹
----bug编号文件夹(名称为buglist中的编号)
----result #(结果)
----'图片'(1.jpg)
----'图片'(2.jpg)
----expect #(期望)
----'图片'(1.jpg)
----'图片'(2.jpg)
'''
bugs_list = cli.add_bug_from_excel("F:\\wyl\\禅道测试\\buglist.xls", "F:\\wyl\\禅道测试\\pics")
for i in bugs_list:
print(i)
将以上代码存储到zentao.py,cd到代码目录,cmd执行:
python ./zentao.py
下载脚本:zentao.zip
下载debuglist模板:buglist.zip