refactor(接口测试): 场景执行历史&执行结果改造

This commit is contained in:
WangXu10 2024-11-13 15:22:49 +08:00 committed by Craftsman
parent 796ae6bb7d
commit 9552f43d1a
11 changed files with 159 additions and 93 deletions

View File

@ -135,7 +135,8 @@ public class ApiReportController {
@GetMapping("/task-report/{id}")
@Operation(summary = "系统-任务中心-接口用例执行任务详情-查看")
@RequiresPermissions(value = {PermissionConstants.SYSTEM_CASE_TASK_CENTER_READ,
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ}, logical = Logical.OR)
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ,
PermissionConstants.PROJECT_API_REPORT_READ, PermissionConstants.PROJECT_API_DEFINITION_CASE_EXECUTE}, logical = Logical.OR)
public ApiTaskReportDTO viewCaseItemReport(@PathVariable String id) {
return apiReportService.viewCaseTaskItemReport(id);
}

View File

@ -167,7 +167,7 @@ public class ApiTestCaseController {
public Pager<List<ApiTestCaseDTO>> page(@Validated @RequestBody ApiTestCasePageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString("id")) ? request.getSortString("id") : "pos desc, id desc");
return PageUtils.setPageInfo(page, apiTestCaseService.page(request, false, true,null));
return PageUtils.setPageInfo(page, apiTestCaseService.page(request, false, true, null));
}
@PostMapping(value = "/statistics")
@ -248,8 +248,11 @@ public class ApiTestCaseController {
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_DEFINITION_CASE_READ, PermissionConstants.PROJECT_API_DEFINITION_CASE_UPDATE})
@CheckOwner(resourceId = "#request.getId()", resourceType = "api_test_case")
public Pager<List<ExecuteReportDTO>> getExecuteList(@Validated @RequestBody ExecutePageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "start_time desc");
String sort = StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "eti.id desc";
if (StringUtils.isNotBlank(sort)) {
sort = sort.replace("start_time", "et.create_time");
}
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), sort);
return PageUtils.setPageInfo(page, apiTestCaseService.getExecuteList(request));
}

View File

@ -274,8 +274,11 @@ public class ApiScenarioController {
@RequiresPermissions(logical = Logical.OR, value = {PermissionConstants.PROJECT_API_SCENARIO_READ, PermissionConstants.PROJECT_API_SCENARIO_UPDATE})
@CheckOwner(resourceId = "#request.getId()", resourceType = "api_scenario")
public Pager<List<ExecuteReportDTO>> getExecuteList(@Validated @RequestBody ExecutePageRequest request) {
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(),
StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "start_time desc");
String sort = StringUtils.isNotBlank(request.getSortString()) ? request.getSortString() : "eti.id desc";
if (StringUtils.isNotBlank(sort)) {
sort = sort.replace("start_time", "et.create_time");
}
Page<Object> page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), sort);
return PageUtils.setPageInfo(page, apiScenarioService.getExecuteList(request));
}

View File

@ -140,7 +140,8 @@ public class ApiScenarioReportController {
@GetMapping("/task-step/{id}")
@Operation(summary = "系统-任务中心-场景用例执行任务详情-查看(任务步骤)")
@RequiresPermissions(value = {PermissionConstants.SYSTEM_CASE_TASK_CENTER_READ,
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ}, logical = Logical.OR)
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ,
PermissionConstants.PROJECT_API_REPORT_READ, PermissionConstants.PROJECT_API_SCENARIO_EXECUTE}, logical = Logical.OR)
public ExecTaskDetailDTO viewScenarioItemReport(@PathVariable String id) {
return apiScenarioReportService.viewScenarioItemReport(id);
}
@ -148,9 +149,10 @@ public class ApiScenarioReportController {
@GetMapping("/task-report/{reportId}/{stepId}")
@Operation(summary = "系统-任务中心-场景用例执行任务详情-查看(步骤结果)")
@RequiresPermissions(value = {PermissionConstants.SYSTEM_CASE_TASK_CENTER_READ,
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ}, logical = Logical.OR)
PermissionConstants.ORGANIZATION_CASE_TASK_CENTER_READ, PermissionConstants.PROJECT_CASE_TASK_CENTER_READ,
PermissionConstants.PROJECT_API_REPORT_READ, PermissionConstants.PROJECT_API_SCENARIO_EXECUTE}, logical = Logical.OR)
public List<ApiScenarioReportDetailDTO> getScenarioReportDetail(@PathVariable String reportId,
@PathVariable String stepId) {
@PathVariable String stepId) {
return apiScenarioReportService.getDetail(reportId, stepId);
}
}

View File

@ -0,0 +1,48 @@
package io.metersphere.api.dto.definition;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* @author wx
*/
@Data
public class ExecHistoryDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "任务项id")
private String itemId;
@Schema(description = "任务id")
private String taskId;
@Schema(description = "执行方式")
private String triggerMode;
@Schema(description = "执行结果")
private String status;
@Schema(description = "状态")
private String execStatus;
@Schema(description = "操作人")
private String createUser;
@Schema(description = "操作时间")
private Long startTime;
@Schema(description = "是否集合报告")
private Boolean integrated;
@Schema(description = "测试计划id")
private String testPlanId;
@Schema(description = "测试计划Num")
private String testPlanNum;
}

View File

@ -2,6 +2,7 @@ package io.metersphere.api.mapper;
import io.metersphere.api.domain.ApiScenario;
import io.metersphere.api.dto.ApiResourceBatchRunInfo;
import io.metersphere.api.dto.definition.ExecHistoryDTO;
import io.metersphere.api.dto.definition.ExecutePageRequest;
import io.metersphere.api.dto.definition.ExecuteReportDTO;
import io.metersphere.api.dto.scenario.*;
@ -105,4 +106,5 @@ public interface ExtApiScenarioMapper {
List<ProjectUserCreateCount> userCreateApiScenarioCount(@Param("projectId") String projectId, @Param("startTime") long startTime, @Param("endTime") long endTime, @Param("userIds") Set<String> userIds);
List<ExecHistoryDTO> selectExecHistory(@Param("request") ExecutePageRequest request);
}

View File

@ -798,4 +798,52 @@
group by api_scenario.create_user;
</select>
<select id="selectExecHistory" resultType="io.metersphere.api.dto.definition.ExecHistoryDTO">
SELECT
et.trigger_mode,
et.task_name,
eti.result as status,
eti.`status` as execStatus,
eti.executor as createUser,
eti.deleted,
et.create_time as startTime,
et.integrated,
tp.id as testPlanId,
tp.num as testPlanNum,
eti.task_id as taskId,
eti.id as itemId
FROM
exec_task_item eti
left JOIN exec_task et ON eti.task_id = et.id
left JOIN test_plan tp on eti.task_origin = tp.id
where eti.case_id = #{request.id}
<include refid="history_filters">
<property name="filter" value="request.filter"/>
</include>
</select>
<sql id="history_filters">
<if test="${filter} != null and ${filter}.size() > 0">
<foreach collection="${filter}.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='integrated'">
and et.integrated in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='status'">
and eti.result in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
<when test="key=='triggerMode'">
and et.trigger_mode in
<include refid="io.metersphere.system.mapper.BaseMapper.filterInWrapper"/>
</when>
</choose>
</if>
</foreach>
</if>
</sql>
</mapper>

View File

@ -58,7 +58,6 @@ import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
@Transactional(rollbackFor = Exception.class)
@ -108,6 +107,8 @@ public class ApiTestCaseService extends MoveNodeService {
private FunctionalCaseTestMapper functionalCaseTestMapper;
@Resource
private UserMapper userMapper;
@Resource
private ExtApiScenarioMapper extApiScenarioMapper;
private static final String CASE_TABLE = "api_test_case";
@ -342,6 +343,7 @@ public class ApiTestCaseService extends MoveNodeService {
}
return returnList;
}
private void buildApiTestCaseDTO(List<ApiTestCaseDTO> apiCaseLists) {
if (CollectionUtils.isNotEmpty(apiCaseLists)) {
List<String> userIds = new ArrayList<>();
@ -569,46 +571,32 @@ public class ApiTestCaseService extends MoveNodeService {
}
public List<ExecuteReportDTO> getExecuteList(ExecutePageRequest request) {
List<ExecuteReportDTO> executeList = extApiTestCaseMapper.getExecuteList(request);
if (CollectionUtils.isEmpty(executeList)) {
return new ArrayList<>();
}
Set<String> userSet = executeList.stream()
.flatMap(apiReport -> Stream.of(apiReport.getCreateUser()))
.collect(Collectors.toSet());
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//执行历史列表
List<String> reportIds = executeList.stream().map(ExecuteReportDTO::getId).toList();
Map<String, ExecuteReportDTO> historyDeletedMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(reportIds)) {
List<ExecuteReportDTO> historyDeletedList = extApiReportMapper.getHistoryDeleted(reportIds);
historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
}
Map<String, String> testPlanIdMap = executeList.stream()
.filter(apiReport -> !StringUtils.equals(apiReport.getTestPlanId(), "NONE"))
.collect(Collectors.toMap(ExecuteReportDTO::getId, ExecuteReportDTO::getTestPlanId));
List<String> testPlanIds = new ArrayList<>(testPlanIdMap.keySet());
Map<String, String> testPlanNumMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(testPlanIds)) {
List<ExecuteReportDTO> testPlanNameLists = extApiTestCaseMapper.getTestPlanNum(testPlanIds);
testPlanNumMap = testPlanNameLists.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, ExecuteReportDTO::getTestPlanNum));
}
Map<String, ExecuteReportDTO> finalHistoryDeletedMap = historyDeletedMap;
Map<String, String> finalTestPlanNumMap = testPlanNumMap;
executeList.forEach(apiReport -> {
apiReport.setOperationUser(userMap.get(apiReport.getCreateUser()));
Date date = new Date(apiReport.getStartTime());
apiReport.setNum(sdf.format(date));
apiReport.setHistoryDeleted(MapUtils.isNotEmpty(finalHistoryDeletedMap) && !finalHistoryDeletedMap.containsKey(apiReport.getId()));
if (MapUtils.isNotEmpty(testPlanIdMap) && testPlanIdMap.containsKey(apiReport.getId())) {
apiReport.setTestPlanNum(StringUtils.join(Translator.get("test_plan"), ": ", finalTestPlanNumMap.get(apiReport.getId())));
}
});
List<ExecHistoryDTO> historyList = extApiScenarioMapper.selectExecHistory(request);
List<ExecuteReportDTO> executeList = handleList(historyList);
return executeList;
}
private List<ExecuteReportDTO> handleList(List<ExecHistoryDTO> historyList) {
List<ExecuteReportDTO> executeReportDTOList = new ArrayList<>();
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(historyList)) {
List<String> userIds = historyList.stream().map(ExecHistoryDTO::getCreateUser).toList();
Map<String, String> userNameMap = userLoginService.getUserNameMap(userIds);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
historyList.forEach(item -> {
ExecuteReportDTO reportDTO = new ExecuteReportDTO();
BeanUtils.copyBean(reportDTO, item);
reportDTO.setOperationUser(userNameMap.get(item.getCreateUser()));
reportDTO.setId(item.getItemId());
reportDTO.setNum(sdf.format(item.getStartTime()));
if (StringUtils.isNotBlank(item.getTestPlanNum())) {
reportDTO.setTestPlanNum(StringUtils.join(Translator.get("test_plan"), ": ", item.getTestPlanNum()));
}
executeReportDTOList.add(reportDTO);
});
}
return executeReportDTOList;
}
public List<OperationHistoryDTO> operationHistoryList(OperationHistoryRequest request) {
return operationHistoryService.listWidthTable(request, CASE_TABLE);
}

View File

@ -7,6 +7,7 @@ import io.metersphere.api.controller.result.ApiResultCode;
import io.metersphere.api.domain.*;
import io.metersphere.api.dto.*;
import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
import io.metersphere.api.dto.definition.ExecHistoryDTO;
import io.metersphere.api.dto.definition.ExecutePageRequest;
import io.metersphere.api.dto.definition.ExecuteReportDTO;
import io.metersphere.api.dto.export.MetersphereApiScenarioExportResponse;
@ -177,6 +178,8 @@ public class ApiScenarioService extends MoveNodeService {
public static final String SCHEDULE = "Schedule";
private static final String SCENARIO_TABLE = "api_scenario";
private static final String SCENARIO = "SCENARIO";
@Resource
private ApiReportRelateTaskMapper apiReportRelateTaskMapper;
public List<ApiScenarioDTO> getScenarioPage(ApiScenarioPageRequest request, boolean isRepeat, String testPlanId) {
@ -1002,7 +1005,7 @@ public class ApiScenarioService extends MoveNodeService {
* 获取待更新的 ApiScenarioStep 列表
*/
public List<ApiScenarioStep> getApiScenarioSteps(ApiScenarioStepCommonDTO parent,
List<ApiScenarioStepRequest> steps, List<ApiScenarioCsvStep> csvSteps) {
List<ApiScenarioStepRequest> steps, List<ApiScenarioCsvStep> csvSteps) {
if (CollectionUtils.isEmpty(steps)) {
return Collections.emptyList();
}
@ -1462,6 +1465,7 @@ public class ApiScenarioService extends MoveNodeService {
return getStepBlobByIds(stepIdList).stream()
.collect(Collectors.toMap(ApiScenarioStepBlob::getId, blob -> new String(blob.getContent())));
}
public List<ApiScenarioStepBlob> getStepBlobByIds(List<String> stepIds) {
if (CollectionUtils.isEmpty(stepIds)) {
return Collections.emptyList();
@ -1736,9 +1740,9 @@ public class ApiScenarioService extends MoveNodeService {
* @param scenarioStepMap 所有场景步骤key 为场景IDvalue 为子步骤列表
*/
public List<ApiScenarioStepDTO> buildStepTree(List<ApiScenarioStepDTO> steps,
Map<String, List<ApiScenarioStepDTO>> parentStepMap,
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap,
Set<String> stepIdSet) {
Map<String, List<ApiScenarioStepDTO>> parentStepMap,
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap,
Set<String> stepIdSet) {
if (CollectionUtils.isEmpty(steps)) {
return Collections.emptyList();
}
@ -2377,46 +2381,11 @@ public class ApiScenarioService extends MoveNodeService {
}
public List<ExecuteReportDTO> getExecuteList(ExecutePageRequest request) {
List<ExecuteReportDTO> executeList = extApiScenarioMapper.getExecuteList(request);
if (CollectionUtils.isEmpty(executeList)) {
return new ArrayList<>();
}
Set<String> userSet = executeList.stream()
.flatMap(apiReport -> Stream.of(apiReport.getCreateUser()))
.collect(Collectors.toSet());
//执行历史列表
List<String> reportIds = executeList.stream().map(ExecuteReportDTO::getId).toList();
Map<String, ExecuteReportDTO> historyDeletedMap = new HashMap<>();
if (CollectionUtils.isNotEmpty(reportIds)) {
List<ExecuteReportDTO> historyDeletedList = extApiScenarioReportMapper.getHistoryDeleted(reportIds);
historyDeletedMap = historyDeletedList.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, Function.identity()));
}
Map<String, String> testPlanIdMap = executeList.stream()
.filter(apiReport -> !StringUtils.equals(apiReport.getTestPlanId(), "NONE"))
.collect(Collectors.toMap(ExecuteReportDTO::getId, ExecuteReportDTO::getTestPlanId));
List<String> testPlanIds = new ArrayList<>(testPlanIdMap.keySet());
Map<String, String> testPlanNumMap = new HashMap<>();
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(testPlanIds)) {
List<ExecuteReportDTO> testPlanNameLists = extApiScenarioReportMapper.getTestPlanNum(testPlanIds);
testPlanNumMap = testPlanNameLists.stream().collect(Collectors.toMap(ExecuteReportDTO::getId, ExecuteReportDTO::getTestPlanNum));
}
Map<String, String> userMap = userLoginService.getUserNameMap(new ArrayList<>(userSet));
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Map<String, ExecuteReportDTO> finalHistoryDeletedMap = historyDeletedMap;
Map<String, String> finalTestPlanNumMap = testPlanNumMap;
executeList.forEach(apiReport -> {
apiReport.setOperationUser(userMap.get(apiReport.getCreateUser()));
Date date = new Date(apiReport.getStartTime());
apiReport.setNum(sdf.format(date));
apiReport.setHistoryDeleted(MapUtils.isNotEmpty(finalHistoryDeletedMap) && !finalHistoryDeletedMap.containsKey(apiReport.getId()));
if (MapUtils.isNotEmpty(testPlanIdMap) && testPlanIdMap.containsKey(apiReport.getId())) {
apiReport.setTestPlanNum(StringUtils.join(Translator.get("test_plan"), ": ", finalTestPlanNumMap.get(apiReport.getId())));
}
});
return executeList;
return apiTestCaseService.getExecuteList(request);
}
public List<OperationHistoryDTO> operationHistoryList(OperationHistoryRequest request) {
return operationHistoryService.listWidthTable(request, SCENARIO_TABLE);
}

View File

@ -117,7 +117,7 @@ public class TestPlanApiCaseBatchRunService {
// 初始化任务
ExecTask execTask = initExecTask(testPlanApiCases.size(), project, userId);
// 初始化任务项
initExecTaskItem(testPlanApiCases, userId, project, execTask);
initExecTaskItem(testPlanApiCases, userId, project, execTask, testPlan.getId());
TestPlanCollection finalRootCollection = rootCollection;
List<TestPlanCollection> finalTestPlanCollections = testPlanCollections;
@ -296,7 +296,7 @@ public class TestPlanApiCaseBatchRunService {
return testPlanApiCases;
}
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiCaseBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask) {
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiCaseBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask, String testPlanId) {
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
for (TestPlanApiCaseBatchRunDTO apiTestCase : apiTestCases) {
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
@ -304,6 +304,7 @@ public class TestPlanApiCaseBatchRunService {
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
execTaskItem.setResourceId(apiTestCase.getId());
execTaskItem.setCaseId(apiTestCase.getCaseId());
execTaskItem.setTaskOrigin(testPlanId);
execTaskItem.setResourceName(apiTestCase.getName());
execTaskItem.setCollectionId(apiTestCase.getTestPlanCollectionId());
execTaskItems.add(execTaskItem);

View File

@ -114,7 +114,7 @@ public class TestPlanApiScenarioBatchRunService {
ExecTask execTask = initExecTask(testPlanApiScenarios.size(), project, userId);
// 初始化任务项
initExecTaskItem(testPlanApiScenarios, userId, project, execTask);
initExecTaskItem(testPlanApiScenarios, userId, project, execTask, testPlan.getId());
TestPlanCollection finalRootCollection = rootCollection;
List<TestPlanCollection> finalTestPlanCollections = testPlanCollections;
@ -274,7 +274,7 @@ public class TestPlanApiScenarioBatchRunService {
return execTask;
}
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiScenarioBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask) {
private List<ExecTaskItem> initExecTaskItem(List<TestPlanApiScenarioBatchRunDTO> apiTestCases, String userId, Project project, ExecTask execTask, String testPlanId) {
List<ExecTaskItem> execTaskItems = new ArrayList<>(apiTestCases.size());
for (TestPlanApiScenarioBatchRunDTO testPlanApiScenario : apiTestCases) {
ExecTaskItem execTaskItem = apiCommonService.newExecTaskItem(execTask.getId(), project.getId(), userId);
@ -282,6 +282,7 @@ public class TestPlanApiScenarioBatchRunService {
execTaskItem.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
execTaskItem.setResourceId(testPlanApiScenario.getId());
execTaskItem.setCaseId(testPlanApiScenario.getCaseId());
execTaskItem.setTaskOrigin(testPlanId);
execTaskItem.setResourceName(testPlanApiScenario.getName());
execTaskItem.setCollectionId(testPlanApiScenario.getTestPlanCollectionId());
execTaskItems.add(execTaskItem);