fix(接口测试): 场景多次引用相同的场景,执行报错
This commit is contained in:
parent
ffd19fae21
commit
0ab72dcf0e
|
@ -44,11 +44,6 @@ public class ExecutionQueue implements Serializable {
|
|||
*/
|
||||
private ApiRunModeConfigDTO runModeConfig;
|
||||
|
||||
/**
|
||||
* 全部场景的请求请求总量,用于计算执行各种指标
|
||||
*/
|
||||
private Long requestCount;
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
|
@ -24,9 +24,4 @@ public class ExecutionQueueDetail implements Serializable {
|
|||
* 当前资源产生的执行报告id
|
||||
*/
|
||||
private String reportId;
|
||||
|
||||
/**
|
||||
* 单个场景要执行的请求总量,用于计算执行各种指标
|
||||
*/
|
||||
private Long requestCount;
|
||||
}
|
|
@ -79,4 +79,11 @@ public class ApiScenarioStepCommonDTO<T extends ApiScenarioStepCommonDTO> {
|
|||
@Valid
|
||||
@Schema(description = "子步骤")
|
||||
private List<T> children;
|
||||
|
||||
/**
|
||||
* 步骤的唯一ID
|
||||
* 引用相同场景的情况原步骤ID可能会重复
|
||||
*/
|
||||
@Schema(description = "执行时需要的步骤唯一ID,引用相同场景的情况原步骤ID可能会重复")
|
||||
private String uniqueId;
|
||||
}
|
||||
|
|
|
@ -57,5 +57,5 @@ public interface ExtApiScenarioMapper {
|
|||
|
||||
Long getPos(String projectId);
|
||||
|
||||
List<ApiScenario> getApiCaseExecuteInfoByIds(List<String> subIds);
|
||||
List<ApiScenario> getScenarioExecuteInfoByIds(@Param("ids") List<String> ids);
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@
|
|||
ORDER BY pos DESC
|
||||
LIMIT 1;
|
||||
</select>
|
||||
<select id="getApiCaseExecuteInfoByIds" resultType="io.metersphere.api.domain.ApiScenario">
|
||||
<select id="getScenarioExecuteInfoByIds" resultType="io.metersphere.api.domain.ApiScenario">
|
||||
select id, name, environment_id, project_id
|
||||
from api_scenario
|
||||
where id in
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import io.metersphere.api.dto.ApiBatchRunInitReportResult;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
|
@ -26,31 +25,11 @@ public class ApiBatchRunBaseService {
|
|||
*/
|
||||
public ExecutionQueue initExecutionqueue(List<String> resourceIds, ApiRunModeConfigDTO runModeConfig, String resourceType, Map<String, String> caseReportMap, String userId) {
|
||||
ExecutionQueue queue = getExecutionQueue(runModeConfig, resourceType, userId);
|
||||
queue.setRequestCount(runModeConfig.isIntegratedReport() ? resourceIds.size() : 1L);
|
||||
List<ExecutionQueueDetail> queueDetails = getExecutionQueueDetails(resourceIds, caseReportMap);
|
||||
apiExecutionQueueService.insertQueue(queue, queueDetails);
|
||||
return queue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化执行队列
|
||||
*
|
||||
* @param resourceIds
|
||||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
public ExecutionQueue initExecutionqueue(List<String> resourceIds, ApiRunModeConfigDTO runModeConfig, String resourceType, ApiBatchRunInitReportResult reportResult, String userId) {
|
||||
Map<String, Long> scenarioCountMap = reportResult.getScenarioCountMap();
|
||||
ExecutionQueue queue = getExecutionQueue(runModeConfig, resourceType, userId);
|
||||
queue.setRequestCount(reportResult.getRequestCount());
|
||||
List<ExecutionQueueDetail> queueDetails = getExecutionQueueDetails(resourceIds, reportResult.getScenarioReportMap());
|
||||
for (ExecutionQueueDetail queueDetail : queueDetails) {
|
||||
queueDetail.setRequestCount(scenarioCountMap.get(queueDetail.getResourceId()));
|
||||
}
|
||||
apiExecutionQueueService.insertQueue(queue, queueDetails);
|
||||
return queue;
|
||||
}
|
||||
|
||||
public List<ExecutionQueueDetail> getExecutionQueueDetails(List<String> resourceIds, Map<String, String> caseReportMap) {
|
||||
List<ExecutionQueueDetail> queueDetails = new ArrayList<>();
|
||||
AtomicInteger sort = new AtomicInteger(1);
|
||||
|
@ -58,7 +37,6 @@ public class ApiBatchRunBaseService {
|
|||
ExecutionQueueDetail queueDetail = new ExecutionQueueDetail();
|
||||
queueDetail.setResourceId(resourceId);
|
||||
queueDetail.setSort(sort.getAndIncrement());
|
||||
queueDetail.setRequestCount(1L);
|
||||
// caseReportMap 为 null ,说明是集合报告,生成一个虚拟的报告ID
|
||||
queueDetail.setReportId(caseReportMap == null ? UUID.randomUUID().toString() : caseReportMap.get(resourceId));
|
||||
queueDetails.add(queueDetail);
|
||||
|
|
|
@ -315,7 +315,7 @@ public class ApiTestCaseBatchRunService {
|
|||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiTestCase, runModeConfig);
|
||||
taskRequest.setQueueId(queue.getQueueId());
|
||||
taskRequest.setRequestCount(queue.getRequestCount());
|
||||
taskRequest.setRequestCount(1l);
|
||||
execute(taskRequest, apiTestCase, apiTestCaseBlob, BeanUtils.copyBean(new ApiDefinitionExecuteInfo(), apiDefinition));
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,15 @@ import io.metersphere.api.domain.ApiScenario;
|
|||
import io.metersphere.api.domain.ApiScenarioRecord;
|
||||
import io.metersphere.api.domain.ApiScenarioReport;
|
||||
import io.metersphere.api.domain.ApiScenarioReportStep;
|
||||
import io.metersphere.api.dto.ApiBatchRunInitReportResult;
|
||||
import io.metersphere.api.dto.ApiScenarioParamConfig;
|
||||
import io.metersphere.api.dto.ApiScenarioParseTmpParam;
|
||||
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
||||
import io.metersphere.api.dto.request.MsScenario;
|
||||
import io.metersphere.api.dto.scenario.*;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioBatchRunRequest;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioDetail;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioParseParam;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepDTO;
|
||||
import io.metersphere.api.mapper.ExtApiScenarioMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
|
@ -24,19 +27,20 @@ import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
|||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.DateUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
|
@ -53,6 +57,8 @@ public class ApiScenarioBatchRunService {
|
|||
private ApiScenarioReportService apiScenarioReportService;
|
||||
@Resource
|
||||
private ApiBatchRunBaseService apiBatchRunBaseService;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
|
@ -95,13 +101,13 @@ public class ApiScenarioBatchRunService {
|
|||
initIntegratedReport(runModeConfig, ids, userId, request.getProjectId());
|
||||
}
|
||||
|
||||
ApiBatchRunInitReportResult reportResult = initReport(ids, runModeConfig, userId);
|
||||
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
|
||||
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_SCENARIO.name(), reportResult, userId);
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_SCENARIO.name(), scenarioReportMap, userId);
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
executeNextTask(queue, nextDetail);
|
||||
|
@ -124,84 +130,84 @@ public class ApiScenarioBatchRunService {
|
|||
apiExecutionSetService.initSet(apiScenarioReport.getId(), ids);
|
||||
}
|
||||
|
||||
ApiBatchRunInitReportResult reportResult = initReport(ids, runModeConfig, userId);
|
||||
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
|
||||
|
||||
// 集成报告,执行前先设置成 RUNNING
|
||||
setRunningIntegrateReport(runModeConfig);
|
||||
|
||||
AtomicInteger errorCount = new AtomicInteger();
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
String reportId = null;
|
||||
try {
|
||||
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(id);
|
||||
if (apiScenarioDetail == null) {
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 用例不存在,则在执行集合中删除
|
||||
apiExecutionSetService.removeItem(runModeConfig.getCollectionReport().getReportId(), id);
|
||||
}
|
||||
LogUtils.info("当前执行任务的用例已删除 {}", id);
|
||||
break;
|
||||
}
|
||||
// 请求数量,集合报告放总的数量,独立报告,放当前场景的请求数量
|
||||
Long requestCount;
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集成报告生成虚拟的报告ID
|
||||
reportId = IDGenerator.nextStr();
|
||||
requestCount = reportResult.getRequestCount();
|
||||
} else {
|
||||
reportId = reportResult.getScenarioReportMap().get(id);
|
||||
requestCount = Optional.ofNullable(reportResult.getScenarioCountMap().get(id)).orElse(0L);
|
||||
}
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiScenarioDetail, runModeConfig);
|
||||
taskRequest.setRequestCount(requestCount);
|
||||
execute(taskRequest, apiScenarioDetail);
|
||||
AtomicInteger errorCount = new AtomicInteger();
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("执行用例失败 {}-{}", reportId, id);
|
||||
LogUtils.error(e);
|
||||
if (errorCount.getAndIncrement() > 10) {
|
||||
LogUtils.error("批量执行用例失败,错误次数超过10次,停止执行");
|
||||
return;
|
||||
String reportId = null;
|
||||
try {
|
||||
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(id);
|
||||
if (apiScenarioDetail == null) {
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 用例不存在,则在执行集合中删除
|
||||
apiExecutionSetService.removeItem(runModeConfig.getCollectionReport().getReportId(), id);
|
||||
}
|
||||
LogUtils.info("当前执行任务的用例已删除 {}", id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集成报告生成虚拟的报告ID
|
||||
reportId = IDGenerator.nextStr();
|
||||
} else {
|
||||
reportId = scenarioReportMap.get(id);
|
||||
}
|
||||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiScenarioDetail, runModeConfig);
|
||||
execute(taskRequest, apiScenarioDetail);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("执行用例失败 {}-{}", reportId, id);
|
||||
LogUtils.error(e);
|
||||
if (errorCount.getAndIncrement() > 10) {
|
||||
LogUtils.error("批量执行用例失败,错误次数超过10次,停止执行");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ApiBatchRunInitReportResult initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
Map<String, String> scenarioReportMap = new HashMap<>();
|
||||
ApiBatchRunInitReportResult reportResult = new ApiBatchRunInitReportResult();
|
||||
Map<String, Long> scenarioCountMap = reportResult.getScenarioCountMap();
|
||||
Boolean isIntegratedReport = runModeConfig.isIntegratedReport();
|
||||
AtomicInteger sort = new AtomicInteger(1);
|
||||
|
||||
List<ApiScenarioReportStep> apiScenarioReportSteps = new ArrayList<>(ids.size());
|
||||
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>(ids.size());
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> apiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiScenario> apiScenarioMap = apiScenarios.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, Function.identity()));
|
||||
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(id);
|
||||
|
||||
if (apiScenarioDetail == null) {
|
||||
ApiScenario apiScenario = apiScenarioMap.get(id);
|
||||
if (apiScenario == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 记录请求数量
|
||||
Long itemCount = getRequestCount(apiScenarioDetail.getSteps());
|
||||
scenarioCountMap.put(id, itemCount);
|
||||
reportResult.setRequestCount(reportResult.getRequestCount() + itemCount);
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 初始化集成报告步骤
|
||||
initIntegratedReportSteps(apiScenarioDetail, runModeConfig.getCollectionReport().getReportId(), sort.getAndIncrement());
|
||||
// 集合报告初始化一级步骤
|
||||
ApiScenarioReportStep apiScenarioReportStep = getApiScenarioReportStep(apiScenario, runModeConfig.getCollectionReport().getReportId(), sort.getAndIncrement());
|
||||
apiScenarioReportSteps.add(apiScenarioReportStep);
|
||||
} else {
|
||||
// 初始化非集成报告
|
||||
String reportId = initScenarioReport(runModeConfig, apiScenarioDetail, userId).getApiScenarioReportId();
|
||||
// 初始化报告步骤
|
||||
apiScenarioService.initScenarioReportSteps(apiScenarioDetail.getSteps(), reportId);
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
String reportId = initScenarioReport(runModeConfig, apiScenario, userId).getApiScenarioReportId();
|
||||
scenarioReportMap.put(id, reportId);
|
||||
}
|
||||
}
|
||||
|
||||
reportResult.setScenarioReportMap(isIntegratedReport ? null : scenarioReportMap);
|
||||
return reportResult;
|
||||
if (CollectionUtils.isNotEmpty(apiScenarioReportSteps)) {
|
||||
apiScenarioReportService.insertApiScenarioReportStep(apiScenarioReportSteps);
|
||||
}
|
||||
|
||||
return isIntegratedReport ? null : scenarioReportMap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -226,18 +232,6 @@ public class ApiScenarioBatchRunService {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化集成报告的报告步骤
|
||||
*/
|
||||
private void initIntegratedReportSteps(ApiScenarioDetail apiScenarioDetail, String reportId, long sort) {
|
||||
// 将当前场景生成一级报告步骤
|
||||
ApiScenarioReportStep apiScenarioReportStep = getApiScenarioReportStep(apiScenarioDetail, reportId, sort);
|
||||
// 初始化报告步骤
|
||||
List<ApiScenarioReportStep> scenarioReportSteps = apiScenarioService.getScenarioReportSteps(apiScenarioReportStep.getStepId(), apiScenarioDetail.getSteps(), reportId);
|
||||
scenarioReportSteps.addFirst(apiScenarioReportStep);
|
||||
apiScenarioReportService.insertApiScenarioReportStep(scenarioReportSteps);
|
||||
}
|
||||
|
||||
private ApiScenarioReportStep getApiScenarioReportStep(ApiScenario apiScenario, String reportId, long sort) {
|
||||
ApiScenarioReportStep apiReportStep = new ApiScenarioReportStep();
|
||||
apiReportStep.setReportId(reportId);
|
||||
|
@ -296,14 +290,6 @@ public class ApiScenarioBatchRunService {
|
|||
}
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(queueDetail.getReportId(), apiScenarioDetail, queue.getRunModeConfig());
|
||||
taskRequest.setQueueId(queue.getQueueId());
|
||||
// 请求数量,集合报告放总的数量,独立报告,放当前场景的请求数量
|
||||
Long requestCount;
|
||||
if (queue.getRunModeConfig().isIntegratedReport()) {
|
||||
requestCount = queue.getRequestCount();
|
||||
} else {
|
||||
requestCount = Optional.ofNullable(queueDetail.getRequestCount()).orElse(0L);
|
||||
}
|
||||
taskRequest.setRequestCount(requestCount);
|
||||
execute(taskRequest, apiScenarioDetail);
|
||||
}
|
||||
|
||||
|
@ -328,7 +314,16 @@ public class ApiScenarioBatchRunService {
|
|||
parseParam.setEnvironmentId(envId);
|
||||
parseParam.setGrouped(envGroup);
|
||||
|
||||
// 初始化报告步骤
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
apiScenarioService.initScenarioReportSteps(apiScenarioDetail.getId(), apiScenarioDetail.getSteps(), runModeConfig.getCollectionReport().getReportId());
|
||||
} else {
|
||||
apiScenarioService.initScenarioReportSteps(apiScenarioDetail.getSteps(), reportId);
|
||||
}
|
||||
|
||||
taskRequest.setReportId(reportId);
|
||||
// 记录请求数量
|
||||
taskRequest.setRequestCount(getRequestCount(apiScenarioDetail.getSteps()));
|
||||
|
||||
ApiScenarioParseTmpParam tmpParam = apiScenarioService.parse(msScenario, apiScenarioDetail.getSteps(), parseParam);
|
||||
|
||||
|
@ -340,7 +335,6 @@ public class ApiScenarioBatchRunService {
|
|||
apiExecuteService.execute(runRequest, taskRequest, parseConfig);
|
||||
}
|
||||
|
||||
|
||||
private TaskRequestDTO getTaskRequestDTO(String reportId, ApiScenarioDetail apiScenarioDetail, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskRequestDTO taskRequest = apiScenarioService.getTaskRequest(reportId, apiScenarioDetail.getId(), apiScenarioDetail.getProjectId(), ApiExecuteRunMode.RUN.name());
|
||||
taskRequest.setSaveResult(true);
|
||||
|
|
|
@ -1379,7 +1379,11 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
* @param reportId
|
||||
*/
|
||||
public void initScenarioReportSteps(List<? extends ApiScenarioStepCommonDTO> steps, String reportId) {
|
||||
List<ApiScenarioReportStep> scenarioReportSteps = getScenarioReportSteps(null, steps, reportId);
|
||||
initScenarioReportSteps(null, steps, reportId);
|
||||
}
|
||||
|
||||
public void initScenarioReportSteps(String parentId, List<? extends ApiScenarioStepCommonDTO> steps, String reportId) {
|
||||
List<ApiScenarioReportStep> scenarioReportSteps = getScenarioReportSteps(parentId, steps, reportId);
|
||||
apiScenarioReportService.insertApiScenarioReportStep(scenarioReportSteps);
|
||||
}
|
||||
|
||||
|
@ -1393,12 +1397,16 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
AtomicLong sort = new AtomicLong(1);
|
||||
List<ApiScenarioReportStep> scenarioReportSteps = new ArrayList<>();
|
||||
for (ApiScenarioStepCommonDTO step : steps) {
|
||||
if (StringUtils.isBlank(step.getUniqueId())) {
|
||||
// 如果没有步骤唯一ID,则生成唯一ID
|
||||
step.setUniqueId(IDGenerator.nextStr());
|
||||
}
|
||||
ApiScenarioReportStep scenarioReportStep = getScenarioReportStep(step, reportId, sort.getAndIncrement());
|
||||
scenarioReportStep.setParentId(parentId);
|
||||
scenarioReportSteps.add(scenarioReportStep);
|
||||
List<? extends ApiScenarioStepCommonDTO> children = step.getChildren();
|
||||
if (CollectionUtils.isNotEmpty(children)) {
|
||||
scenarioReportSteps.addAll(getScenarioReportSteps(step.getId(), children, reportId));
|
||||
scenarioReportSteps.addAll(getScenarioReportSteps(step.getUniqueId(), children, reportId));
|
||||
}
|
||||
}
|
||||
return scenarioReportSteps;
|
||||
|
@ -1407,7 +1415,7 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
private ApiScenarioReportStep getScenarioReportStep(ApiScenarioStepCommonDTO step, String reportId, long sort) {
|
||||
ApiScenarioReportStep scenarioReportStep = new ApiScenarioReportStep();
|
||||
scenarioReportStep.setReportId(reportId);
|
||||
scenarioReportStep.setStepId(step.getId());
|
||||
scenarioReportStep.setStepId(step.getUniqueId());
|
||||
scenarioReportStep.setSort(sort);
|
||||
scenarioReportStep.setName(step.getName());
|
||||
scenarioReportStep.setStepType(step.getStepType());
|
||||
|
@ -1637,6 +1645,11 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
parseParam.getRequestCount().getAndIncrement();
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(step.getUniqueId())) {
|
||||
// 如果调试的时候前端没有传步骤唯一ID,则生成唯一ID
|
||||
step.setUniqueId(IDGenerator.nextStr());
|
||||
}
|
||||
|
||||
// 将步骤详情解析生成对应的MsTestElement
|
||||
AbstractMsTestElement msTestElement = stepParser.parseTestElement(step,
|
||||
MapUtils.isNotEmpty(resourceDetailMap) ? resourceDetailMap.getOrDefault(step.getResourceId(), StringUtils.EMPTY) : StringUtils.EMPTY, stepDetailMap.get(step.getId()));
|
||||
|
@ -1648,8 +1661,9 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
}
|
||||
msTestElement.setProjectId(step.getProjectId());
|
||||
msTestElement.setResourceId(step.getResourceId());
|
||||
msTestElement.setStepId(step.getId());
|
||||
msTestElement.setName(step.getName());
|
||||
// 步骤ID,设置为唯一ID
|
||||
msTestElement.setStepId(step.getUniqueId());
|
||||
|
||||
// 记录引用的资源ID和项目ID,下载执行文件时需要使用
|
||||
parseParam.getRefProjectIds().add(step.getProjectId());
|
||||
|
@ -1961,7 +1975,7 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
.stream()
|
||||
.collect(Collectors.groupingBy(step -> Optional.ofNullable(step.getParentId()).orElse(StringUtils.EMPTY)));
|
||||
|
||||
List<ApiScenarioStepDTO> steps = buildStepTree(currentScenarioParentStepMap.get(StringUtils.EMPTY), currentScenarioParentStepMap, scenarioStepMap);
|
||||
List<ApiScenarioStepDTO> steps = buildStepTree(currentScenarioParentStepMap.get(StringUtils.EMPTY), currentScenarioParentStepMap, scenarioStepMap, new HashSet<>());
|
||||
|
||||
// 设置部分引用的步骤的启用状态
|
||||
setPartialRefStepsEnable(steps, stepDetailMap);
|
||||
|
@ -2011,11 +2025,22 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
*/
|
||||
private List<ApiScenarioStepDTO> buildStepTree(List<ApiScenarioStepDTO> steps,
|
||||
Map<String, List<ApiScenarioStepDTO>> parentStepMap,
|
||||
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap) {
|
||||
Map<String, List<ApiScenarioStepDTO>> scenarioStepMap,
|
||||
Set<String> stepIdSet) {
|
||||
if (CollectionUtils.isEmpty(steps)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
steps.forEach(step -> {
|
||||
|
||||
for (int i = 0; i < steps.size(); i++) {
|
||||
ApiScenarioStepDTO step = steps.get(i);
|
||||
if (stepIdSet.contains(step.getId())) {
|
||||
// 如果步骤ID已存在,说明引用了两个相同的场景,其子步骤ID可能会重复,导致引用的同一个对象
|
||||
// 这里重新new一个对象,避免执行时,处理为同一个步骤
|
||||
step = BeanUtils.copyBean(new ApiScenarioStepDTO(), step);
|
||||
steps.set(i, step);
|
||||
}
|
||||
stepIdSet.add(step.getId());
|
||||
|
||||
// 获取当前步骤的子步骤
|
||||
List<ApiScenarioStepDTO> children = Optional.ofNullable(parentStepMap.get(step.getId())).orElse(new ArrayList<>(0));
|
||||
if (isRefOrPartialScenario(step)) {
|
||||
|
@ -2029,21 +2054,22 @@ public class ApiScenarioService extends MoveNodeService {
|
|||
});
|
||||
|
||||
if (CollectionUtils.isEmpty(children)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果当前步骤是引用的场景,获取该场景的子步骤
|
||||
Map<String, List<ApiScenarioStepDTO>> childStepMap = scenarioSteps
|
||||
.stream()
|
||||
.collect(Collectors.groupingBy(item -> Optional.ofNullable(item.getParentId()).orElse(StringUtils.EMPTY)));
|
||||
step.setChildren(buildStepTree(children, childStepMap, scenarioStepMap));
|
||||
step.setChildren(buildStepTree(children, childStepMap, scenarioStepMap, stepIdSet));
|
||||
} else {
|
||||
if (CollectionUtils.isEmpty(children)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
step.setChildren(buildStepTree(children, parentStepMap, scenarioStepMap));
|
||||
step.setChildren(buildStepTree(children, parentStepMap, scenarioStepMap, stepIdSet));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 排序
|
||||
return steps.stream()
|
||||
.sorted(Comparator.comparing(ApiScenarioStepDTO::getSort))
|
||||
|
|
Loading…
Reference in New Issue