Files
cdtestplant_v1/utils/util.py
2025-04-29 18:09:00 +08:00

408 lines
15 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from typing import List
from apps.dict.models import DictItem
from apps.project.models import TestDemand
from html.parser import HTMLParser
from django.db.models import QuerySet
# 导入生成文档检查器log - 单例模式
from apps.createSeiTaiDocument.extensions.logger import GenerateLogger
logger = GenerateLogger(model='字典模块')
# 传入一个字符串数字以及字典标志code返回真实的title名字
def get_str_dict(a, dict_code):
dict_obj = DictItem.objects.filter(dict__code=dict_code, key=a).first()
if dict_obj:
return dict_obj.title
else:
# 如果用户没填写内容则记录检查中心log
logger.write_warning_log(fragment='字典数据缺失', message=f'字典数据{dict_code}数据缺失,请检查相应数据是否存在')
return ''
# 传入一个字符串数字以及字典标志code返回字典所属的缩写(show_title)
def get_str_abbr(a, dict_code):
dict_obj = DictItem.objects.filter(dict__code=dict_code, key=a).first()
if dict_obj:
return dict_obj.show_title
else:
logger.write_warning_log(fragment='字典数据缺失',
message=f'查询字段数据缩写问题,字典数据{dict_code}数据可能缺失')
return ""
# 传入一个字符串数组测试项类型字典标志code返回(真实title,sort)
def get_str_dict_plus(a, dict_code):
dict_obj = DictItem.objects.filter(dict__code=dict_code, key=a).first()
if dict_obj:
return dict_obj.title, dict_obj.sort
else:
logger.write_warning_log(fragment='字典数据查询错误', message=f'字典{dict_code}未查询到数据,请检查')
return "", 1
# 找到testType字典中的缩写例如“DC”“FT”
def get_testType(a, dict_code):
dict_obj = DictItem.objects.filter(dict__code=dict_code, key=a).first()
if dict_obj:
return dict_obj.show_title
else:
logger.write_warning_log(fragment='字典数据查询错误',
message=f'查询字段数据缩写问题,字典数据{dict_code}数据可能缺失')
return ""
# 标识处理获取测试需求测试项的生成文档的ident标识
def get_ident(test_item):
# key_index = int(test_item.key.split("-")[-1]) + 1
# test_index = str(key_index).rjust(3, '0')
reveal_ident = "_".join(
["XQ", get_testType(test_item.testType, "testType"), test_item.ident])
return reveal_ident
# 标识处理传入demand的ident以及case返回case的ident
def get_case_ident(demand_ident, case):
key_index = int(case.key.split("-")[-1]) + 1
test_index = str(key_index).rjust(3, '0')
reveal_ident = "_".join([demand_ident.replace("XQ", "YL"), test_index])
return reveal_ident
# 传入字典code以及字符串数组返回一个数组每个数组是dict
def get_list_dict(dict_code: str, str_list: List[str]):
result = []
qss = DictItem.objects.filter(dict__code=dict_code)
for st in str_list:
res = {}
for qs in qss:
if st == qs.key:
res['ident_version'] = qs.title
res['doc_name'] = qs.doc_name
res['publish_date'] = qs.publish_date
res['source'] = qs.source
result.append(res)
return result
# 传入字典code以及字符串数组返回一个列表每个元素是dict包含字典item很多信息
def get_list_dict_info(dict_code, str_list):
"""传入字典的字符串列表输出每个元素为dict的列表信息"""
result = []
qss = DictItem.objects.filter(dict__code=dict_code) # type:ignore
for st in str_list:
res = {}
for qs in qss:
if st == qs.key:
res['title'] = qs.title
res['index'] = qs.sort
result.append(res)
return result
# 传入字典code以及单个字典字符串输出一个dict带信息
def get_dict_info(dict_code, item_str):
"""传入字典的字符串单个表示输出dict包含排序index字段"""
qss = DictItem.objects.filter(dict__code=dict_code)
res = {}
for qs in qss:
if item_str == qs.key:
res['title'] = qs.title
res['index'] = qs.sort
return res
# 简单HTML解析器 - 解析富文本的parser - 复杂的使用apps/createDocument/extensions/parse_rich_text.py
class MyHTMLParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.allStrList = []
def error(self, message):
print("HTML解析器出错error信息为", message)
def handle_starttag(self, tag, attrs):
if tag == 'img':
img_base64 = attrs[0][1]
self.allStrList.append(img_base64)
def handle_endtag(self, tag):
pass
def handle_data(self, data):
if data != '\n':
self.allStrList.append(data)
# 不提取图片的HTML解析器
class MyHTMLParser_p(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.allStrList = []
def handle_data(self, data):
if data != '\n':
self.allStrList.append(data)
def create_problem_grade_str(problems):
"""传入问题qs生成到文档的字符串严重问题4个、一般问题10个"""
problem_r1_grade_dict = {}
for problem in problems:
grade_key: str = get_str_dict(problem.grade, 'problemGrade')
if grade_key in problem_r1_grade_dict.keys():
problem_r1_grade_dict[grade_key] += 1
else:
problem_r1_grade_dict[grade_key] = 1
problem_r1_grade_list = []
for key, value in problem_r1_grade_dict.items():
problem_r1_grade_list.append("".join([f"{key}问题", f"{value}"]))
return "".join(problem_r1_grade_list)
def create_problem_type_str(problems):
"""传入问题qs生成到文档的字符串文档问题1个程序问题10个"""
problem_r1_type_dict = {}
for problem in problems:
type_key: str = get_str_dict(problem.type, 'problemType')
if type_key in problem_r1_type_dict.keys():
problem_r1_type_dict[type_key] += 1
else:
problem_r1_type_dict[type_key] = 1
problem_r1_type_list = []
for key, value in problem_r1_type_dict.items():
problem_r1_type_list.append("".join([f"{key}", f"{value}"]))
return "".join(problem_r1_type_list)
def create_str_testType_list(cases):
"""传入用例的qs生成其测试类型的字符串例如包含xxx测试5个xxx测试11个返回的是元组第二个元素表示测试类型个数"""
test_type_set: set = set()
for case in cases:
demand: TestDemand = case.test
test_type_set.add(demand.testType)
test_type_list = get_list_dict_info('testType', list(test_type_set))
test_type_list.sort(key=lambda x: int(x['index']))
round1_testType_list = list(map(lambda x: x['title'], test_type_list))
return round1_testType_list, len(test_type_list)
def util_func(item):
"""辅助函数将下面函数返回的summary_list改造为以需求类型执行统计列表"""
transform_item = {'title': item['title'], 'total_count': 0, 'exe_count': 0, 'not_exe_count': 0, 'pass_count': 0,
'not_pass_count': 0}
for it in item['demand_list']:
transform_item['total_count'] += it['total_count']
transform_item['exe_count'] += it['exe_count']
transform_item['not_exe_count'] += it['not_exe_count']
transform_item['pass_count'] += it['pass_count']
transform_item['not_pass_count'] += it['not_pass_count']
return transform_item
def create_demand_summary(demands: QuerySet, project_ident: str):
"""
[
{
'title':'功能测试_5',
'demand_list':[
{
'name': '测试项1',
'total_count': 1,
'exe_count': 1,
'not_exe_count': 0,
'pass_count': 1,
'not_pass_count': 0,
'conclusion': '通过',
'problems': '/'
}
]
},
]
"""
summary_dict = {} # 后面再变为数组
# 1.首先根据testType字段生成一个一个dict
for demand in demands:
# 取出testType -> '4'(后面查字典)
test_type_num = demand.testType
# 查出需求类型的sort与testType真实名字,组合为一个字符串作为key
testTypeStr, testTypeSort = get_str_dict_plus(test_type_num, 'testType')
testType_info = testTypeStr + '_' + str(testTypeSort)
demand_dict = {
'name': demand.name,
'total_count': 0,
'exe_count': 0,
'not_exe_count': 0,
'pass_count': 0,
'not_pass_count': 0,
'conclusion': '通过',
'problems': "/"
}
# 查询当前测试需求下用例
demand_problem_list = set()
for case in demand.tcField.all():
demand_dict['total_count'] += 1
# 要遍历下面的测试步骤
isPassed = True
isExe = True
for step in case.step.all():
# 所有步骤有一个未通过则是未通过,所有都执行则是已执行
if step.passed == '2':
isPassed = False
isExe = True
break
if step.passed == '3':
isExe = False
if isPassed:
demand_dict['pass_count'] += 1
else:
demand_dict['not_pass_count'] += 1
demand_dict['conclusion'] = '未通过'
if isExe:
demand_dict['exe_count'] += 1
else:
demand_dict['not_exe_count'] += 1
# 查询每个用例下面的问题单将问题单的ident弄出来
for problem in case.caseField.all():
problem_ident = 'PT_' + project_ident + '_' + problem.ident.rjust(3, '0')
demand_problem_list.add(problem_ident)
if len(list(demand_problem_list)) > 0:
demand_dict['problems'] = "\a".join(list(demand_problem_list))
if testType_info in summary_dict.keys():
summary_dict[testType_info].append(demand_dict)
else:
summary_dict[testType_info] = [demand_dict]
summary_list = []
for key, value in summary_dict.items():
one_dict = {
'title': key,
'demand_list': value
}
summary_list.append(one_dict)
# 根据其排序
summary_list.sort(key=lambda x: int(x['title'].split('_')[-1]))
# 然后将_5这种替换掉
for one in summary_list:
one['title'] = one['title'].split("_")[0]
# ~~~~还需要返回一个 -> 测试类型的用例执行情况
demandType_exe_list = list(map(util_func, summary_list))
return summary_list, demandType_exe_list
def create_problem_table(problems):
"""传入问题单qs输出按问题种类分的问题统计表的数据"""
res_list = [{
'name': '一般问题',
'xq_count': 0,
'sj_count': 0,
'wd_count': 0,
'bm_count': 0,
'data_count': 0,
'other_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '严重问题',
'xq_count': 0,
'sj_count': 0,
'wd_count': 0,
'bm_count': 0,
'data_count': 0,
'other_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '建议',
'xq_count': 0,
'sj_count': 0,
'wd_count': 0,
'bm_count': 0,
'data_count': 0,
'other_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '重大问题',
'xq_count': 0,
'sj_count': 0,
'wd_count': 0,
'bm_count': 0,
'data_count': 0,
'other_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}]
for problem in problems:
index = int(problem.grade) - 1
if problem.type == '1':
res_list[index]['other_count'] += 1
elif problem.type == '2':
res_list[index]['wd_count'] += 1
elif problem.type == '3':
res_list[index]['bm_count'] += 1
elif problem.type == '4':
res_list[index]['sj_count'] += 1
elif problem.type == '5':
res_list[index]['xq_count'] += 1
elif problem.type == '6':
res_list[index]['data_count'] += 1
# 是否归零
if problem.status == '1':
res_list[index]['closed_count'] += 1
else:
res_list[index]['non_closed_count'] += 1
return res_list
def create_problem_type_table(problems):
"""传入问题qs解析出按测试类型分的问题统计表格"""
res_list = [{
'name': '一般问题',
'wd_count': 0,
'jt_count': 0,
'dm_count': 0,
'dt_count': 0,
'data_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '严重问题',
'wd_count': 0,
'jt_count': 0,
'dm_count': 0,
'dt_count': 0,
'data_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '建议',
'wd_count': 0,
'jt_count': 0,
'dm_count': 0,
'dt_count': 0,
'data_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}, {
'name': '重大问题',
'wd_count': 0,
'jt_count': 0,
'dm_count': 0,
'dt_count': 0,
'data_count': 0,
'closed_count': 0,
'non_closed_count': 0,
}]
for problem in problems:
index = int(problem.grade) - 1
belong_demand: TestDemand = problem.case.all()[0].test
if belong_demand.testType == '8': # 属于文档审查问题
res_list[index]['wd_count'] += 1
elif belong_demand.testType == '15': # 属于静态分析问题
res_list[index]['jt_count'] += 1
elif belong_demand.testType == '2' or belong_demand.testType == '3': # 属于代码审查和走查
res_list[index]['dm_count'] += 1
else: # 属于动态发现问题
res_list[index]['dt_count'] += 1
# 是否归零
if problem.status == '1':
res_list[index]['closed_count'] += 1
else:
res_list[index]['non_closed_count'] += 1
return res_list
def get_demand_testTypes(demand_qs) -> str:
"""传入测试项qs返回字符串类似于“静态分析、代码审查、功能测试等”"""
testType_list = list(demand_qs.values("testType").distinct().order_by('testType'))
t_code_list = [item['testType'] for item in testType_list]
t_code_list = get_list_dict_info('testType', t_code_list)
t_code_list.sort(key=lambda x: int(x['index']))
t_str = [item['title'] for item in t_code_list]
return ''.join(t_str) if len(t_str) > 0 else "测试"