【Python】Python实现Excel用例直接导入testlink-UI界面小工具

时间:2023-03-09 18:40:52
【Python】Python实现Excel用例直接导入testlink-UI界面小工具

1.写在前面

testlink上传用例一种方法是excel转换为xml,然后再用xml上传,还有一种是调用api进行上传。
最开始写了个转换工具,是将excel转换为xml,然后在testlink里上传,最后发现当模块变多以后xml太多,一个一个上传太麻烦,所以尝试用调用api的方式来上传用例,并且打包成exe小工具。

2.环境

python3.7.4
testlink1.9.14 ( 1.9.14和19都测试通过 )

3.用到的库

tkinter :python自带,用于编写简易的界面

xlrd:第三方库,需要pip安装,读取excel的库,也可以使用pandas代替

TestLink-API-Python-client:第三方库,需要pip安装,提供python和testlink交互的api

4.完成效果图

4.1 用模板写好用例

【Python】Python实现Excel用例直接导入testlink-UI界面小工具

4.2 选择好上传项目和根目录导入或者子目录导入(这里用的是testlink中文网的演示地址)

【Python】Python实现Excel用例直接导入testlink-UI界面小工具

4.3 点击导入后弹出导入进度条

【Python】Python实现Excel用例直接导入testlink-UI界面小工具

4.4 导入成功,查看testlink里的用例

【Python】Python实现Excel用例直接导入testlink-UI界面小工具
【Python】Python实现Excel用例直接导入testlink-UI界面小工具

5.部分代码

5.1 testlink方法二次封装

 @dataclass
class ClientTestLink:
"""
testlink二次封装
"""
user_api_pwd: str
client_url: str = "http://你的testlink地址/testlink/lib/api/xmlrpc/v1/xmlrpc.php" def __post_init__(self):
self.tlc = TestlinkAPIClient(self.client_url, self.user_api_pwd) def get_projects(self):
"""获取testLink内所有项目"""
project_list = []
for project in self.tlc.getProjects():
project_list.append([project.get("id"), project.get("name")])
return project_list def get_project_id_by_name(self, project_name):
"""获取项目id根据项目名称"""
return self.tlc.getProjectIDByName(project_name) def get_test_suites(self, project_id):
"""获取指定项目里(需要项目id)的测试用例集"""
test_suite_list = []
test_suites = self.tlc.getFirstLevelTestSuitesForTestProject(project_id)
for test_suite in test_suites:
test_suite_list.append([test_suite.get("id"), test_suite.get("name")])
return test_suite_list def get_test_suite_id(self, project_id, test_suite_name):
"""查询一级目录"""
all_suites = self.get_test_suites(project_id)
for i in all_suites:
if i[1] == test_suite_name:
return i[0]
else:
pass
return False def get_test_suite_for_test_suite(self, test_suite_id):
"""查询用例集下是否含有某用例集"""
try:
test_suite_id = self.tlc.getTestSuitesForTestSuite(test_suite_id)
return test_suite_id
except Exception:
return False def create_test_suite(self, project_id: int, test_suite_name: str, parent_id: int = None):
"""判断是否拥有测试用例集,如果没有就创建测试用例集"""
suite_data = self.tlc.createTestSuite(project_id, test_suite_name, test_suite_name, parentid=parent_id)
cheak_bool = isinstance(suite_data, list)
if cheak_bool:
return suite_data[0].get("id")
else:
if parent_id is None:
return self.get_test_suite_id(project_id=project_id, test_suite_name=test_suite_name)
else:
for k, v in self.get_test_suite_for_test_suite(parent_id).items():
if isinstance(v, dict):
if v.get("name") == test_suite_name:
return v.get("id")
else:
pass
else:
return self.get_test_suite_for_test_suite(parent_id).get("id") def create_test_case(self, project_id: int, test_suite_id: int, test_case_name, summary, preconditions,
step, result, author_login):
"""创建测试用例"""
self.tlc.initStep(step, result, 1)
return self.tlc.createTestCase(testprojectid=project_id,
testsuiteid=test_suite_id,
testcasename=test_case_name,
summary=summary,
preconditions=preconditions,
authorlogin=author_login
) def update_project_keywords(self, project_id, test_case_id, keyword_value):
"""加关键字"""
test_case = self.tlc.getTestCase(testcaseid=test_case_id)[0]
args = {
'testprojectid': project_id,
'testcaseexternalid': test_case['full_tc_external_id'],
'version': int(test_case['version'])
}
keyword = self.tlc.addTestCaseKeywords({args['testcaseexternalid']: [keyword_value]})
return keyword def update_custom_field(self, project_id, test_case_id, custom_fields: dict):
"""更新自定义字段"""
test_case = self.tlc.getTestCase(testcaseid=test_case_id)[0]
args = {
'testprojectid': project_id,
'testcaseexternalid': test_case['full_tc_external_id'],
'version': int(test_case['version'])
}
custom = self.tlc.updateTestCaseCustomFieldDesignValue(
args['testcaseexternalid'], args['version'], args['testprojectid'], custom_fields)
return custom

5.2 从根目录上传用例

 def run_root(excel_file_name, project_id, username, api_token):
"""
创建用例
"""
case_num = get_all_case_num(excel_file_name)
win2 = tk.Tk()
# 设置标题
win2.title("导入任务")
# 设置大小和位置
win2.geometry("220x100")
# 禁止改变窗口大小
win2.resizable(0, 0)
mpb = ttk.Progressbar(win2, orient="horizontal", length=150, mode="determinate")
mpb.place(x="", y="")
mpb["maximum"] = case_num
mpb["value"] = 0
upload_label = tk.Label(win2, text='正在导入用例...(切勿关闭)', fg='red')
upload_label.place(x="", y="")
upload_label_text = tk.Label(win2, text='', fg='red')
upload_label_text.place(x="", y="")
upload_per_label = tk.Label(win2, text='', fg='red')
upload_per_label.place(x="", y="")
# 读取excel,获取数据
datacases = xlrd.open_workbook(excel_file_name) sheets = datacases.sheet_names() for sheet in sheets:
sheet_1 = datacases.sheet_by_name(sheet) # ====================测试用例功能模块============================== row_num = sheet_1.nrows
for i in range(1, row_num):
# 定义默认步骤编号第一步
catalog_1 = sheet_1.cell_value(i, 0) # 一级目录
catalog_2 = sheet_1.cell_value(i, 1) # 二级目录
catalog_3 = sheet_1.cell_value(i, 2) # 三级目录
test_case_name = sheet_1.cell_value(i, 3) # 用例名称
summary = sheet_1.cell_value(i, 4) # 摘要
key_words = sheet_1.cell_value(i, 5) # 关键字
test_case_level = sheet_1.cell_value(i, 6) # 用例级别
preconditions = sheet_1.cell_value(i, 7) # 预置条件
step = sheet_1.cell_value(i, 8) # 操作步骤
step_list = []
# 处理换行
for i_step in step.split('\n'):
step_list.append("<p>" + i_step + "</p>")
step = ''.join(step_list)
expected_results = sheet_1.cell_value(i, 9) # 预期结果
expected_results_list = []
# 处理换行
for i_expected_results in expected_results.split('\n'):
expected_results_list.append("<p>" + i_expected_results + "</p>")
expected_results = ''.join(expected_results_list) # 创建一级目录
test_suite_id = ClientTestLink(api_token).create_test_suite(project_id=project_id,
test_suite_name=catalog_1)
# 创建二级目录
if catalog_2:
test_suite_id = ClientTestLink(api_token).create_test_suite(project_id=project_id,
test_suite_name=catalog_2,
parent_id=test_suite_id)
# 创建三级目录
if catalog_3:
test_suite_id = ClientTestLink(api_token).create_test_suite(project_id=project_id,
test_suite_name=catalog_3,
parent_id=test_suite_id)
result = ClientTestLink(api_token).create_test_case(
project_id=project_id,
test_suite_id=test_suite_id,
test_case_name=test_case_name,
summary=summary,
preconditions=preconditions,
step=step,
result=expected_results,
author_login=username) test_case_id = result[0].get("id")
# 添加关键字
ClientTestLink(api_token).update_project_keywords(project_id=project_id,
test_case_id=test_case_id,
keyword_value=key_words)
# 添加自定义字段
ClientTestLink(api_token).update_custom_field(project_id=project_id,
test_case_id=test_case_id,
custom_fields={"优先级": test_case_level})
mpb["value"] = i
upload_label_text.config(text=f"<{i}/{case_num}>")
upload_per_label.config(text=f"{((i / case_num) * 100):.2f}%")
win.update()
print(f"{test_case_id}-上传用例成功")
win2.destroy()

6.写在最后

等稍后整理好后会把整个源码放出来,因为写的比较着急,很多代码逻辑没考虑到,欢迎指出,指出必改。