Files
cdtestplant_v1/apps/createDocument/controllers/jl.py
2025-04-29 18:09:00 +08:00

155 lines
7.3 KiB
Python

# 内置模块导入
from pathlib import Path
# 导入框架相关
from django.db import transaction
from django.shortcuts import get_object_or_404
from ninja_extra import api_controller, ControllerBase, route
# 导入权限相关
from ninja_extra.permissions import IsAuthenticated
from ninja_jwt.authentication import JWTAuth
# 导入数据库模型
from apps.project.models import Project
from apps.dict.models import Dict
from docxtpl import InlineImage
# 导入文档处理相关
from docxtpl import DocxTemplate
# 导入自己工具
from utils.chapter_tools.csx_chapter import create_csx_chapter_dict
from utils.util import get_ident, get_case_ident, get_testType
from utils.chen_response import ChenResponse
from utils.path_utils import project_path
from apps.createDocument.extensions.parse_rich_text import RichParser
# @api_controller("/generateJL", tags=['生成测试记录系列'], auth=JWTAuth(), permissions=[IsAuthenticated])
@api_controller("/generateJL", tags=['生成测试记录系列'])
class GenerateControllerJL(ControllerBase):
@route.get("/create/caserecord", url_name="create-caserecord")
@transaction.atomic
def create_caserecord(self, id: int):
"""生成测试记录表格"""
project_path_str = project_path(id)
project_obj = get_object_or_404(Project, id=id)
# 测试用例记录模版位置
record_template_path = Path.cwd() / 'media' / project_path_str / 'form_template/jl' / '测试用例记录.docx'
# 打开模版文档
doc = DocxTemplate(record_template_path)
# 准备返回的测试类型数组的嵌套
test_type_len = Dict.objects.get(code='testType').dictItem.count() # 测试类型的个数
type_number_list = [i for i in range(1, test_type_len + 1)] # 测试类型编号对应的列表
list_list = [[] for j in range(1, test_type_len + 1)] # 每个测试类型组合为一个列表[[],[],[],[]]
# 查询出第一轮次
round_one = project_obj.pField.filter(key=0).first()
# 测试项的章节号预置处理 - 根据轮次生成list和dict的二维数据
demand_prefix = '6.2'
testType_list, last_chapter_items = create_csx_chapter_dict(round_one)
# 找出所有测试项
testDemands = round_one.rtField.all()
# 首先轮询所有测试需求
for demand in testDemands:
type_index = type_number_list.index(int(demand.testType))
demand_ident = get_ident(demand)
# ~~~组装测试项~~~
demand_last_chapter = last_chapter_items[demand.testType].index(demand.key) + 1
demand_chapter = ".".join([demand_prefix, str(testType_list.index(demand.testType) + 1),
str(demand_last_chapter)])
demand_dict = {
'name': demand.name,
'ident': demand_ident,
'chapter': demand_chapter,
'item': []
}
# ~~~这里组装测试项里面的测试用例~~~
for case in demand.tcField.all():
step_list = []
index = 1
for one in case.step.all():
# 这里需要对operation富文本处理
rich_parser = RichParser(one.operation)
desc_list = rich_parser.get_final_list(doc, img_size=68)
# 这里需要对result富文本处理
rich_parser2 = RichParser(one.result)
res_list = rich_parser2.get_final_list(doc, img_size=75)
# 组装用例里面的步骤dict
passed = '通过'
if one.passed == '2':
passed = '未通过'
elif one.passed == '3':
passed = '未执行'
step_dict = {
'index': index,
'operation': desc_list,
'expect': one.expect,
'result': res_list,
'passed': passed,
}
index += 1
step_list.append(step_dict)
# 这里判断里面的单个步骤的执行情况,来输出一个整个用例的执行情况
exe_noncount = 0
execution_str = '已执行'
for ste in step_list:
if ste.get('execution') == '3':
exe_noncount += 1
if exe_noncount > 0 and exe_noncount != len(step_list):
execution_str = '部分执行'
elif exe_noncount == len(step_list):
execution_str = '未执行'
else:
execution_str = '已执行'
# 查询所有的problem
problem_list = []
problem_prefix = "PT"
proj_ident = project_obj.ident
for problem in case.caseField.all():
problem_list.append("_".join([problem_prefix, proj_ident, problem.ident]))
# 组装用例的dict
rich_parser3 = RichParser(case.timing_diagram)
timing_diagram = rich_parser3.get_final_list(doc, img_size=115, height=50)
has_timing_diagram = False
if len(timing_diagram) > 0:
if isinstance(timing_diagram[0], InlineImage):
has_timing_diagram = True
case_dict = {
'name': case.name,
'ident': get_case_ident(demand_ident, case),
'summary': case.summarize,
'initialization': case.initialization,
'premise': case.premise,
'design_person': case.designPerson,
'test_person': case.testPerson,
'monitor_person': case.monitorPerson,
'step': step_list,
'execution': execution_str,
'time': str(case.exe_time) if case.exe_time is not None else str(case.update_datetime),
'problems': "".join(problem_list),
# 2025年4月24日新增
'has_timing_diagram': has_timing_diagram,
'timing_diagram': timing_diagram,
}
demand_dict['item'].append(case_dict)
list_list[type_index].append(demand_dict)
# 定义渲染上下文
context = {}
output_list = []
for (index, li) in enumerate(list_list):
qs = Dict.objects.get(code="testType").dictItem.get(key=str(index + 1)) # type:ignore
context_str = qs.title
sort = qs.sort
table = {
"type": context_str,
"item": li,
"sort": sort
}
output_list.append(table)
# 排序
output_list = sorted(output_list, key=(lambda x: x["sort"]))
context["data"] = output_list
doc.render(context)
try:
doc.save(Path.cwd() / "media" / project_path_str / "output_dir/jl" / "测试用例记录.docx")
return ChenResponse(status=200, code=200, message="文档生成成功!")
except PermissionError as e:
return ChenResponse(status=400, code=400, message="模版文件已打开,请关闭后再试,{0}".format(e))