feat(接口测试): 测试计划接口和场景批量执行
This commit is contained in:
parent
62280513fd
commit
6b6f75ab2f
|
@ -3,7 +3,6 @@ package io.metersphere.api.dto.definition;
|
|||
import io.metersphere.api.dto.ApiRunModeRequest;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
|
@ -15,10 +14,6 @@ public class ApiTestCaseBatchRunRequest extends ApiTestCaseBatchRequest implemen
|
|||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "接口pk")
|
||||
@Size(max = 50, message = "{api_definition.id.length_range}")
|
||||
private String apiDefinitionId;
|
||||
|
||||
@Valid
|
||||
@Schema(description = "运行模式配置")
|
||||
private ApiRunModeRequest runModeConfig;
|
||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.api.service;
|
|||
import io.metersphere.api.domain.ApiScenarioReport;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
|
||||
import io.metersphere.sdk.dto.api.task.TaskInfo;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
|
@ -92,4 +93,12 @@ public class ApiBatchRunBaseService {
|
|||
private static String formatRate(double rate) {
|
||||
return String.format("%.2f", rate * 100);
|
||||
}
|
||||
|
||||
public TaskInfo setBatchRunTaskInfoParam(ApiRunModeConfigDTO runModeConfig, TaskInfo taskInfo) {
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(false);
|
||||
taskInfo.setNeedParseScript(true);
|
||||
taskInfo.setRunModeConfig(runModeConfig);
|
||||
return taskInfo;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,16 +311,11 @@ public class ApiTestCaseBatchRunService {
|
|||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
public TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiTestCaseService.getTaskInfo(projectId, ApiExecuteRunMode.RUN.name());
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(false);
|
||||
taskInfo.setNeedParseScript(true);
|
||||
taskInfo.setRunModeConfig(runModeConfig);
|
||||
return taskInfo;
|
||||
return apiBatchRunBaseService.setBatchRunTaskInfoParam(runModeConfig, taskInfo);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 预生成用例的执行报告
|
||||
*
|
||||
|
@ -346,8 +341,7 @@ public class ApiTestCaseBatchRunService {
|
|||
return apiTestCaseRecords;
|
||||
}
|
||||
|
||||
|
||||
private ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, ApiTestCase apiTestCase, String userId) {
|
||||
public ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, ApiTestCase apiTestCase, String userId) {
|
||||
ApiReport apiReport = getApiReport(runModeConfig, userId);
|
||||
apiReport.setEnvironmentId(apiTestCaseService.getEnvId(runModeConfig, apiTestCase));
|
||||
apiReport.setName(apiTestCase.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
|
|
|
@ -24,6 +24,7 @@ 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;
|
||||
|
@ -33,6 +34,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -78,7 +80,7 @@ public class ApiScenarioBatchRunService {
|
|||
*/
|
||||
private void batchRun(ApiScenarioBatchRunRequest request, String userId) {
|
||||
try {
|
||||
if (StringUtils.equals(request.getRunModeConfig().getRunMode(), ApiBatchRunMode.PARALLEL.name())) {
|
||||
if (isParallel(request.getRunModeConfig().getRunMode())) {
|
||||
parallelExecute(request, userId);
|
||||
} else {
|
||||
serialExecute(request, userId);
|
||||
|
@ -88,6 +90,10 @@ public class ApiScenarioBatchRunService {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean isParallel(String runMode) {
|
||||
return StringUtils.equals(runMode, ApiBatchRunMode.PARALLEL.name());
|
||||
}
|
||||
|
||||
/**
|
||||
* 串行批量执行
|
||||
*
|
||||
|
@ -149,42 +155,32 @@ public class ApiScenarioBatchRunService {
|
|||
|
||||
|
||||
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
Map<String, String> scenarioReportMap = new HashMap<>();
|
||||
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)));
|
||||
List<ApiScenario> finalApiScenarios = apiScenarios;
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> finalApiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiScenario> apiScenarioMap = apiScenarios.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, Function.identity()));
|
||||
apiScenarios = new ArrayList<>(ids.size());
|
||||
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
// 按照ID顺序排序
|
||||
ApiScenario apiScenario = apiScenarioMap.get(id);
|
||||
if (apiScenario == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集合报告初始化一级步骤
|
||||
ApiScenarioReportStep apiScenarioReportStep = getApiScenarioReportStep(apiScenario, runModeConfig.getCollectionReport().getReportId(), sort.getAndIncrement());
|
||||
apiScenarioReportSteps.add(apiScenarioReportStep);
|
||||
} else {
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
String reportId = initScenarioReport(runModeConfig, apiScenario, userId).getApiScenarioReportId();
|
||||
scenarioReportMap.put(id, reportId);
|
||||
}
|
||||
apiScenarios.add(apiScenario);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(apiScenarioReportSteps)) {
|
||||
apiScenarioReportService.insertApiScenarioReportStep(apiScenarioReportSteps);
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 集合报告初始化一级步骤
|
||||
initApiScenarioReportStep(apiScenarios, runModeConfig.getCollectionReport().getReportId());
|
||||
return null;
|
||||
} else {
|
||||
// 非集合报告,初始化独立报告,执行时初始化步骤
|
||||
return initScenarioReport(runModeConfig, apiScenarios, userId);
|
||||
}
|
||||
|
||||
return isIntegratedReport ? null : scenarioReportMap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,14 +195,21 @@ public class ApiScenarioBatchRunService {
|
|||
}
|
||||
}
|
||||
|
||||
private ApiScenarioReportStep getApiScenarioReportStep(ApiScenario apiScenario, String reportId, long sort) {
|
||||
ApiScenarioReportStep apiReportStep = new ApiScenarioReportStep();
|
||||
apiReportStep.setReportId(reportId);
|
||||
apiReportStep.setStepId(apiScenario.getId());
|
||||
apiReportStep.setSort(sort);
|
||||
apiReportStep.setName(apiScenario.getName());
|
||||
apiReportStep.setStepType(ApiExecuteResourceType.API_SCENARIO.name());
|
||||
return apiReportStep;
|
||||
public void initApiScenarioReportStep(List<ApiScenario> apiScenarios, String reportId) {
|
||||
AtomicLong sort = new AtomicLong(1);
|
||||
List<ApiScenarioReportStep> apiScenarioReportSteps = new ArrayList<>(apiScenarios.size());
|
||||
for (ApiScenario apiScenario : apiScenarios) {
|
||||
ApiScenarioReportStep apiReportStep = new ApiScenarioReportStep();
|
||||
apiReportStep.setReportId(reportId);
|
||||
apiReportStep.setStepId(apiScenario.getId());
|
||||
apiReportStep.setSort(sort.getAndIncrement());
|
||||
apiReportStep.setName(apiScenario.getName());
|
||||
apiReportStep.setStepType(ApiExecuteResourceType.API_SCENARIO.name());
|
||||
apiScenarioReportSteps.add(apiReportStep);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(apiScenarioReportSteps)) {
|
||||
apiScenarioReportService.insertApiScenarioReportStep(apiScenarioReportSteps);
|
||||
}
|
||||
}
|
||||
|
||||
private ApiRunModeConfigDTO getRunModeConfig(ApiScenarioBatchRunRequest request) {
|
||||
|
@ -289,13 +292,25 @@ public class ApiScenarioBatchRunService {
|
|||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
public TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiScenarioRunService.getTaskInfo(projectId, ApiExecuteRunMode.RUN.name());
|
||||
taskInfo.setSaveResult(true);
|
||||
taskInfo.setRealTime(false);
|
||||
taskInfo.setNeedParseScript(true);
|
||||
taskInfo.setRunModeConfig(runModeConfig);
|
||||
return taskInfo;
|
||||
return apiBatchRunBaseService.setBatchRunTaskInfoParam(runModeConfig, taskInfo);
|
||||
}
|
||||
|
||||
public Map<String, String> initScenarioReport(ApiRunModeConfigDTO runModeConfig, List<ApiScenario> apiScenarios, String userId) {
|
||||
List<ApiScenarioReport> apiScenarioReports = new ArrayList<>(apiScenarios.size());
|
||||
List<ApiScenarioRecord> apiScenarioRecords = new ArrayList<>(apiScenarios.size());
|
||||
for (ApiScenario apiScenario : apiScenarios) {
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, apiScenario, userId);
|
||||
apiScenarioReport.setId(IDGenerator.nextStr());
|
||||
apiScenarioReports.add(apiScenarioReport);
|
||||
// 创建报告和用例的关联关系
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(apiScenario, apiScenarioReport);
|
||||
apiScenarioRecords.add(apiScenarioRecord);
|
||||
}
|
||||
apiScenarioReportService.insertApiScenarioReport(apiScenarioReports, apiScenarioRecords);
|
||||
return apiScenarioRecords.stream().collect(Collectors.toMap(ApiScenarioRecord::getApiScenarioId, ApiScenarioRecord::getApiScenarioReportId));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -335,9 +350,11 @@ public class ApiScenarioBatchRunService {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public void updateStopOnFailureReport(ExecutionQueue queue) {
|
||||
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
|
||||
if (BooleanUtils.isFalse(runModeConfig.isIntegratedReport())) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ExecutionQueueDetail queueDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
if (queueDetail == null) {
|
||||
|
@ -361,19 +378,18 @@ public class ApiScenarioBatchRunService {
|
|||
|
||||
queueDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
}
|
||||
if (runModeConfig.isIntegratedReport()) {
|
||||
// 获取未执行的请求数,更新统计指标
|
||||
String reportId = runModeConfig.getCollectionReport().getReportId();
|
||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId);
|
||||
Long pendingCount = requestCount + report.getPendingCount();
|
||||
report.setPendingCount(pendingCount);
|
||||
// 计算各种通过率
|
||||
long total = apiScenarioReportService.getRequestTotal(report);
|
||||
report = apiBatchRunBaseService.computeRequestRate(report, total);
|
||||
report.setStatus(ReportStatus.ERROR.name());
|
||||
report.setExecStatus(ExecStatus.COMPLETED.name());
|
||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||
}
|
||||
|
||||
// 获取未执行的请求数,更新统计指标
|
||||
String reportId = runModeConfig.getCollectionReport().getReportId();
|
||||
ApiScenarioReport report = apiScenarioReportMapper.selectByPrimaryKey(reportId);
|
||||
Long pendingCount = requestCount + report.getPendingCount();
|
||||
report.setPendingCount(pendingCount);
|
||||
// 计算各种通过率
|
||||
long total = apiScenarioReportService.getRequestTotal(report);
|
||||
report = apiBatchRunBaseService.computeRequestRate(report, total);
|
||||
report.setStatus(ReportStatus.ERROR.name());
|
||||
report.setExecStatus(ExecStatus.COMPLETED.name());
|
||||
apiScenarioReportMapper.updateByPrimaryKeySelective(report);
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("失败停止,补充报告步骤失败:", e);
|
||||
}
|
||||
|
|
|
@ -1197,9 +1197,10 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, RUN_REAL_TIME, addApiScenario.getId(), "reportId");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void batchRun() throws Exception {
|
||||
mockPost("/api/run", "");
|
||||
mockPost("/api/batch/run", "");
|
||||
|
||||
ApiScenarioBatchRunRequest request = new ApiScenarioBatchRunRequest();
|
||||
List<String> ids = new ArrayList<>();
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.plan.constants.TestPlanResourceConfig;
|
|||
import io.metersphere.plan.dto.request.*;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
|
||||
import io.metersphere.plan.service.TestPlanApiCaseBatchRunService;
|
||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||
import io.metersphere.plan.service.TestPlanApiCaseLogService;
|
||||
import io.metersphere.plan.service.TestPlanApiCaseService;
|
||||
|
@ -43,6 +44,8 @@ public class TestPlanApiCaseController {
|
|||
@Resource
|
||||
private TestPlanApiCaseService testPlanApiCaseService;
|
||||
@Resource
|
||||
private TestPlanApiCaseBatchRunService testPlanApiCaseBatchRunService;
|
||||
@Resource
|
||||
private TestPlanManagementService testPlanManagementService;
|
||||
@Resource
|
||||
private TestPlanService testPlanService;
|
||||
|
@ -128,5 +131,13 @@ public class TestPlanApiCaseController {
|
|||
}
|
||||
|
||||
|
||||
@PostMapping("/batch/run")
|
||||
@Operation(summary = "批量执行")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||
// @CheckOwner(resourceId = "#request.getId()", resourceType = "test_plan_api_case") todo
|
||||
public void batchRun(@Validated @RequestBody TestPlanApiCaseBatchRunRequest request) {
|
||||
testPlanApiCaseBatchRunService.asyncBatchRun(request, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
//TODO 批量移动 (计划集内)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@ import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
|||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioTreeRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiScenarioPageResponse;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRunRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||
import io.metersphere.plan.service.TestPlanApiCaseBatchRunService;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioBatchRunService;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
|
||||
|
@ -33,15 +37,8 @@ public class TestPlanApiScenarioController {
|
|||
|
||||
@Resource
|
||||
private TestPlanApiScenarioService testPlanApiScenarioService;
|
||||
|
||||
@GetMapping("/run/{id}")
|
||||
@Operation(summary = "接口测试-接口场景管理-场景执行")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||
// @CheckOwner(resourceId = "#id", resourceType = "test_plan_api_scenario")
|
||||
public TaskRequestDTO run(@PathVariable String id, @RequestParam(required = false) String reportId) {
|
||||
return testPlanApiScenarioService.run(id, reportId, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@Resource
|
||||
private TestPlanApiScenarioBatchRunService testPlanApiScenarioBatchRunService;
|
||||
|
||||
@PostMapping("/page")
|
||||
@Operation(summary = "测试计划-已关联场景用例列表分页查询")
|
||||
|
@ -68,4 +65,20 @@ public class TestPlanApiScenarioController {
|
|||
public List<BaseTreeNode> getTree(@Validated @RequestBody TestPlanApiScenarioTreeRequest request) {
|
||||
return testPlanApiScenarioService.getTree(request);
|
||||
}
|
||||
|
||||
@GetMapping("/run/{id}")
|
||||
@Operation(summary = "接口测试-接口场景管理-场景执行")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||
// @CheckOwner(resourceId = "#id", resourceType = "test_plan_api_scenario")
|
||||
public TaskRequestDTO run(@PathVariable String id, @RequestParam(required = false) String reportId) {
|
||||
return testPlanApiScenarioService.run(id, reportId, SessionUtils.getUserId());
|
||||
}
|
||||
|
||||
@PostMapping("/batch/run")
|
||||
@Operation(summary = "批量执行")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
|
||||
// @CheckOwner(resourceId = "#request.getId()", resourceType = "test_plan_api_case") todo
|
||||
public void batchRun(@Validated @RequestBody TestPlanApiScenarioBatchRunRequest request) {
|
||||
testPlanApiScenarioBatchRunService.asyncBatchRun(request, SessionUtils.getUserId());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.plan.dto.request;
|
||||
|
||||
import io.metersphere.api.dto.ApiRunModeRequest;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class TestPlanApiCaseBatchRunRequest extends TestPlanApiCaseBatchRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ApiRunModeRequest runModeConfig;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package io.metersphere.plan.dto.request;
|
||||
|
||||
import io.metersphere.api.dto.ApiRunModeRequest;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class TestPlanApiScenarioBatchRunRequest extends BasePlanCaseBatchRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Valid
|
||||
@Schema(description = "运行模式配置")
|
||||
private ApiRunModeRequest runModeConfig;
|
||||
}
|
|
@ -65,4 +65,6 @@ public interface ExtTestPlanApiCaseMapper {
|
|||
* @return 计划功能用例集合
|
||||
*/
|
||||
List<TestPlanApiCase> getPlanApiCaseByIds(@Param("planIds") List<String> planIds);
|
||||
|
||||
List<TestPlanApiCase> getApiCaseExecuteInfoByIds(@Param("ids") List<String> ids);
|
||||
}
|
||||
|
|
|
@ -670,4 +670,13 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getApiCaseExecuteInfoByIds" resultType="io.metersphere.plan.domain.TestPlanApiCase">
|
||||
select id, test_plan_id, api_case_id, environment_id
|
||||
from test_plan_api_case
|
||||
where id in
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
|
@ -55,4 +55,6 @@ public interface ExtTestPlanApiScenarioMapper {
|
|||
* @return 计划功能用例集合
|
||||
*/
|
||||
List<TestPlanApiScenario> getPlanApiScenarioByIds(@Param("planIds") List<String> planIds);
|
||||
|
||||
List<TestPlanApiScenario> getScenarioExecuteInfoByIds(@Param("ids") List<String> ids);
|
||||
}
|
||||
|
|
|
@ -386,4 +386,13 @@
|
|||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<select id="getScenarioExecuteInfoByIds" resultType="io.metersphere.plan.domain.TestPlanApiScenario">
|
||||
SELECT id, test_plan_id, api_scenario_id, environment_id
|
||||
FROM test_plan_api_scenario
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
|
@ -0,0 +1,271 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.api.domain.ApiReport;
|
||||
import io.metersphere.api.domain.ApiReportStep;
|
||||
import io.metersphere.api.domain.ApiTestCase;
|
||||
import io.metersphere.api.domain.ApiTestCaseRecord;
|
||||
import io.metersphere.api.mapper.ApiTestCaseMapper;
|
||||
import io.metersphere.api.mapper.ExtApiTestCaseMapper;
|
||||
import io.metersphere.api.service.ApiBatchRunBaseService;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.definition.ApiReportService;
|
||||
import io.metersphere.api.service.definition.ApiTestCaseBatchRunService;
|
||||
import io.metersphere.api.service.definition.ApiTestCaseService;
|
||||
import io.metersphere.api.service.queue.ApiExecutionQueueService;
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanApiCase;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseBatchRunRequest;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanApiCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueueDetail;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.LogUtils;
|
||||
import io.metersphere.sdk.util.SubListUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanApiCaseBatchRunService {
|
||||
@Resource
|
||||
private ApiTestCaseMapper apiTestCaseMapper;
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
@Resource
|
||||
private ExtApiTestCaseMapper extApiTestCaseMapper;
|
||||
@Resource
|
||||
private ExtTestPlanApiCaseMapper extTestPlanApiCaseMapper;
|
||||
@Resource
|
||||
private TestPlanApiCaseService testPlanApiCaseService;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
@Resource
|
||||
private ApiReportService apiReportService;
|
||||
@Resource
|
||||
private ApiTestCaseBatchRunService apiTestCaseBatchRunService;
|
||||
@Resource
|
||||
private ApiBatchRunBaseService apiBatchRunBaseService;
|
||||
@Resource
|
||||
private ApiTestCaseService apiTestCaseService;
|
||||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
public void asyncBatchRun(TestPlanApiCaseBatchRunRequest request, String userId) {
|
||||
Thread.startVirtualThread(() -> batchRun(request, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
private void batchRun(TestPlanApiCaseBatchRunRequest request, String userId) {
|
||||
try {
|
||||
if (StringUtils.equals(request.getRunModeConfig().getRunMode(), ApiBatchRunMode.PARALLEL.name())) {
|
||||
parallelExecute(request, userId);
|
||||
} else {
|
||||
serialExecute(request, userId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("批量执行用例失败: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 串行批量执行
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void serialExecute(TestPlanApiCaseBatchRunRequest request, String userId) throws Exception {
|
||||
List<String> ids = testPlanApiCaseService.doSelectIds(request);
|
||||
// todo 查询测试规划
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.API_CASE.name(), userId);
|
||||
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
|
||||
executeNextTask(queue, nextDetail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 并行批量执行
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void parallelExecute(TestPlanApiCaseBatchRunRequest request, String userId) {
|
||||
List<String> ids = testPlanApiCaseService.doSelectIds(request);
|
||||
|
||||
// todo 查询测试规划
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
List<TestPlanApiCase> testPlanApiCases = new ArrayList<>(ids.size());
|
||||
List<ApiTestCase> apiTestCases = new ArrayList<>(ids.size());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> testPlanApiCases.addAll(extTestPlanApiCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
|
||||
List<String> caseIds = testPlanApiCases.stream()
|
||||
.map(TestPlanApiCase::getApiCaseId).collect(Collectors.toList());
|
||||
|
||||
// 分批查询
|
||||
SubListUtils.dealForSubList(caseIds, 100, subIds -> apiTestCases.addAll(extApiTestCaseMapper.getApiCaseExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiTestCase> apiCaseMap = apiTestCases.stream()
|
||||
.collect(Collectors.toMap(ApiTestCase::getId, Function.identity()));
|
||||
|
||||
// 初始化报告,返回用例和报告的 map
|
||||
Map<String, String> caseReportMap = initParallelReport(runModeConfig, testPlanApiCases, apiCaseMap, userId);
|
||||
|
||||
List<TaskItem> taskItems = new ArrayList<>(ids.size());
|
||||
|
||||
// 这里ID顺序和队列的ID顺序保持一致
|
||||
for (String id : ids) {
|
||||
String reportId = caseReportMap.get(id);
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, id);
|
||||
taskItem.setRequestCount(1L);
|
||||
taskItems.add(taskItem);
|
||||
}
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(testPlan.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
}
|
||||
|
||||
private Map<String, String> initParallelReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiCase> testPlanApiCases, Map<String, ApiTestCase> caseMap, String userId) {
|
||||
// 初始化非集成报告
|
||||
List<ApiTestCaseRecord> apiTestCaseRecords = initApiReport(runModeConfig, testPlanApiCases, caseMap, userId);
|
||||
return apiTestCaseRecords.stream()
|
||||
.collect(Collectors.toMap(ApiTestCaseRecord::getApiTestCaseId, ApiTestCaseRecord::getApiReportId));
|
||||
}
|
||||
|
||||
private ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId, long sort) {
|
||||
ApiReportStep apiReportStep = new ApiReportStep();
|
||||
apiReportStep.setReportId(reportId);
|
||||
apiReportStep.setStepId(apiTestCase.getId());
|
||||
apiReportStep.setSort(sort);
|
||||
apiReportStep.setName(apiTestCase.getName());
|
||||
apiReportStep.setStepType(ApiExecuteResourceType.API_CASE.name());
|
||||
return apiReportStep;
|
||||
}
|
||||
|
||||
private ApiRunModeConfigDTO getRunModeConfig(TestPlanApiCaseBatchRunRequest request) {
|
||||
ApiRunModeConfigDTO runModeConfig = BeanUtils.copyBean(new ApiRunModeConfigDTO(), request.getRunModeConfig());
|
||||
return runModeConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行串行的下一个任务
|
||||
*
|
||||
* @param queue
|
||||
* @param queueDetail
|
||||
*/
|
||||
public void executeNextTask(ExecutionQueue queue, ExecutionQueueDetail queueDetail) {
|
||||
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
|
||||
String resourceId = queueDetail.getResourceId();
|
||||
|
||||
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(resourceId);
|
||||
|
||||
if (testPlanApiCase == null) {
|
||||
LogUtils.info("当前执行任务的用例已删除 {}", resourceId);
|
||||
return;
|
||||
}
|
||||
|
||||
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
|
||||
|
||||
// 独立报告,执行到当前任务时初始化报告
|
||||
String reportId = initApiReport(runModeConfig, List.of(testPlanApiCase), Map.of(apiTestCase.getId(), apiTestCase), queue.getUserId()).get(0).getApiReportId();
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(reportId, apiTestCase, runModeConfig);
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
taskRequest.getTaskItem().setRequestCount(1L);
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
}
|
||||
|
||||
private TaskRequestDTO getTaskRequestDTO(String reportId, ApiTestCase apiTestCase, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskRequestDTO taskRequest = new TaskRequestDTO();
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, apiTestCase.getId());
|
||||
TaskInfo taskInfo = getTaskInfo(apiTestCase.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskInfo(taskInfo);
|
||||
taskRequest.setTaskItem(taskItem);
|
||||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskBatchRequestDTO getTaskBatchRequestDTO(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskBatchRequestDTO taskRequest = new TaskBatchRequestDTO();
|
||||
TaskInfo taskInfo = getTaskInfo(projectId, runModeConfig);
|
||||
taskRequest.setTaskInfo(taskInfo);
|
||||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiTestCaseBatchRunService.getTaskInfo(projectId, runModeConfig);
|
||||
taskInfo.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
|
||||
return taskInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @return
|
||||
*/
|
||||
public List<ApiTestCaseRecord> initApiReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiCase> testPlanApiCases,
|
||||
Map<String, ApiTestCase> caseMap, String userId) {
|
||||
List<ApiReport> apiReports = new ArrayList<>();
|
||||
List<ApiTestCaseRecord> apiTestCaseRecords = new ArrayList<>();
|
||||
List<ApiReportStep> apiReportSteps = new ArrayList<>();
|
||||
|
||||
for (TestPlanApiCase testPlanApiCase : testPlanApiCases) {
|
||||
ApiTestCase apiTestCase = caseMap.get(testPlanApiCase.getApiCaseId());
|
||||
// 初始化报告
|
||||
ApiReport apiReport = getApiReport(runModeConfig, testPlanApiCase, apiTestCase, userId);
|
||||
apiReports.add(apiReport);
|
||||
// 创建报告和用例的关联关系
|
||||
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport);
|
||||
apiTestCaseRecords.add(apiTestCaseRecord);
|
||||
apiReportSteps.add(getApiReportStep(apiTestCase, apiReport.getId(), 1));
|
||||
}
|
||||
apiReportService.insertApiReport(apiReports, apiTestCaseRecords);
|
||||
apiReportService.insertApiReportStep(apiReportSteps);
|
||||
return apiTestCaseRecords;
|
||||
}
|
||||
|
||||
|
||||
private ApiReport getApiReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiCase testPlanApiCase, ApiTestCase apiTestCase, String userId) {
|
||||
ApiReport apiReport = apiTestCaseBatchRunService.getApiReport(runModeConfig, apiTestCase, userId);
|
||||
apiReport.setEnvironmentId(getEnvId(runModeConfig, testPlanApiCase));
|
||||
apiReport.setTestPlanCaseId(testPlanApiCase.getId());
|
||||
return apiReport;
|
||||
}
|
||||
|
||||
public String getEnvId(ApiRunModeConfigDTO runModeConfig, TestPlanApiCase testPlanApiCase) {
|
||||
return StringUtils.isBlank(runModeConfig.getEnvironmentId()) ? testPlanApiCase.getEnvironmentId() : runModeConfig.getEnvironmentId();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.api.domain.ApiScenario;
|
||||
import io.metersphere.api.domain.ApiScenarioRecord;
|
||||
import io.metersphere.api.domain.ApiScenarioReport;
|
||||
import io.metersphere.api.mapper.ApiScenarioMapper;
|
||||
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;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioBatchRunService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioReportService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioRunService;
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||
import io.metersphere.sdk.constants.TaskTriggerMode;
|
||||
import io.metersphere.sdk.dto.api.task.*;
|
||||
import io.metersphere.sdk.dto.queue.ExecutionQueue;
|
||||
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.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanApiScenarioBatchRunService {
|
||||
@Resource
|
||||
private TestPlanApiScenarioService testPlanApiScenarioService;
|
||||
@Resource
|
||||
private ApiExecuteService apiExecuteService;
|
||||
@Resource
|
||||
private ApiExecutionQueueService apiExecutionQueueService;
|
||||
@Resource
|
||||
private ApiScenarioReportService apiScenarioReportService;
|
||||
@Resource
|
||||
private ApiScenarioBatchRunService apiScenarioBatchRunService;
|
||||
@Resource
|
||||
private ApiBatchRunBaseService apiBatchRunBaseService;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
@Resource
|
||||
private ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
|
||||
@Resource
|
||||
private ApiScenarioMapper apiScenarioMapper;
|
||||
@Resource
|
||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
@Resource
|
||||
private ApiScenarioRunService apiScenarioRunService;
|
||||
@Resource
|
||||
private TestPlanMapper testPlanMapper;
|
||||
|
||||
/**
|
||||
* 异步批量执行
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
public void asyncBatchRun(TestPlanApiScenarioBatchRunRequest request, String userId) {
|
||||
Thread.startVirtualThread(() -> batchRun(request, userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行
|
||||
*
|
||||
* @param request
|
||||
* @param userId
|
||||
*/
|
||||
private void batchRun(TestPlanApiScenarioBatchRunRequest request, String userId) {
|
||||
try {
|
||||
if (StringUtils.equals(request.getRunModeConfig().getRunMode(), ApiBatchRunMode.PARALLEL.name())) {
|
||||
parallelExecute(request, userId);
|
||||
} else {
|
||||
serialExecute(request, userId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogUtils.error("批量执行用例失败: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 串行批量执行
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void serialExecute(TestPlanApiScenarioBatchRunRequest request, String userId) throws Exception {
|
||||
// List<String> ids = testPlanApiScenarioService.doSelectIds(request, false); //todo
|
||||
List<String> ids = request.getSelectIds();
|
||||
// todo 查询测试规划
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
// 先初始化集成报告,设置好报告ID,再初始化执行队列
|
||||
ExecutionQueue queue = apiBatchRunBaseService.initExecutionqueue(ids, runModeConfig, ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name(), userId);
|
||||
// 执行第一个任务
|
||||
ExecutionQueueDetail nextDetail = apiExecutionQueueService.getNextDetail(queue.getQueueId());
|
||||
executeNextTask(queue, nextDetail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 并行批量执行
|
||||
*
|
||||
* @param request
|
||||
*/
|
||||
public void parallelExecute(TestPlanApiScenarioBatchRunRequest request, String userId) {
|
||||
// List<String> ids = testPlanApiScenarioService.doSelectIds(request, false); //todo
|
||||
List<String> ids = request.getSelectIds();
|
||||
|
||||
// todo 查询测试规划
|
||||
ApiRunModeConfigDTO runModeConfig = getRunModeConfig(request);
|
||||
|
||||
Map<String, String> scenarioReportMap = initReport(ids, runModeConfig, userId);
|
||||
|
||||
List<TaskItem> taskItems = ids.stream()
|
||||
.map(id -> apiExecuteService.getTaskItem(scenarioReportMap.get(id), id)).toList();
|
||||
|
||||
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(request.getTestPlanId());
|
||||
|
||||
TaskBatchRequestDTO taskRequest = getTaskBatchRequestDTO(testPlan.getProjectId(), runModeConfig);
|
||||
taskRequest.setTaskItems(taskItems);
|
||||
|
||||
apiExecuteService.batchExecute(taskRequest);
|
||||
}
|
||||
|
||||
private ApiRunModeConfigDTO getRunModeConfig(TestPlanApiScenarioBatchRunRequest request) {
|
||||
ApiRunModeConfigDTO runModeConfig = BeanUtils.copyBean(new ApiRunModeConfigDTO(), request.getRunModeConfig());
|
||||
return runModeConfig;
|
||||
}
|
||||
|
||||
private Map<String, String> initReport(List<String> ids, ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
List<TestPlanApiScenario> testPlanApiScenarios = new ArrayList<>(ids.size());
|
||||
|
||||
List<ApiScenario> apiScenarios = new ArrayList<>(ids.size());
|
||||
// 分批查询
|
||||
List<TestPlanApiScenario> finalTestPlanApiScenarios = testPlanApiScenarios;
|
||||
SubListUtils.dealForSubList(ids, 100, subIds -> finalTestPlanApiScenarios.addAll(extTestPlanApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
List<String> caseIds = testPlanApiScenarios.stream().map(TestPlanApiScenario::getApiScenarioId).toList();
|
||||
List<ApiScenario> finalApiScenarios = apiScenarios;
|
||||
SubListUtils.dealForSubList(caseIds, 100, subIds -> finalApiScenarios.addAll(extApiScenarioMapper.getScenarioExecuteInfoByIds(subIds)));
|
||||
|
||||
Map<String, ApiScenario> apiScenarioMap = apiScenarios.stream()
|
||||
.collect(Collectors.toMap(ApiScenario::getId, Function.identity()));
|
||||
|
||||
Map<String, TestPlanApiScenario> testPlanApiScenarioMap = testPlanApiScenarios.stream()
|
||||
.collect(Collectors.toMap(TestPlanApiScenario::getId, Function.identity()));
|
||||
|
||||
testPlanApiScenarios = new ArrayList<>(ids.size());
|
||||
for (String id : ids) {
|
||||
// 按照ID顺序排序
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMap.get(id);
|
||||
if (testPlanApiScenario == null) {
|
||||
break;
|
||||
}
|
||||
testPlanApiScenarios.add(testPlanApiScenario);
|
||||
}
|
||||
// 初始化独立报告,执行时初始化步骤
|
||||
return initScenarioReport(runModeConfig, testPlanApiScenarios, apiScenarioMap, userId);
|
||||
}
|
||||
|
||||
public Map<String, String> initScenarioReport(ApiRunModeConfigDTO runModeConfig, List<TestPlanApiScenario> testPlanApiScenarios,
|
||||
Map<String, ApiScenario> apiScenarioMap, String userId) {
|
||||
List<ApiScenarioReport> apiScenarioReports = new ArrayList<>(testPlanApiScenarios.size());
|
||||
List<ApiScenarioRecord> apiScenarioRecords = new ArrayList<>(testPlanApiScenarios.size());
|
||||
for (TestPlanApiScenario testPlanApiScenario : testPlanApiScenarios) {
|
||||
ApiScenario apiScenario = apiScenarioMap.get(testPlanApiScenario.getApiScenarioId());
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, userId);
|
||||
apiScenarioReport.setId(IDGenerator.nextStr());
|
||||
apiScenarioReports.add(apiScenarioReport);
|
||||
// 创建报告和用例的关联关系
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(apiScenario, apiScenarioReport);
|
||||
apiScenarioRecords.add(apiScenarioRecord);
|
||||
}
|
||||
apiScenarioReportService.insertApiScenarioReport(apiScenarioReports, apiScenarioRecords);
|
||||
return apiScenarioRecords.stream().collect(Collectors.toMap(ApiScenarioRecord::getApiScenarioId, ApiScenarioRecord::getApiScenarioReportId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行串行的下一个任务
|
||||
*
|
||||
* @param queue
|
||||
* @param queueDetail
|
||||
*/
|
||||
public void executeNextTask(ExecutionQueue queue, ExecutionQueueDetail queueDetail) {
|
||||
ApiRunModeConfigDTO runModeConfig = queue.getRunModeConfig();
|
||||
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(queueDetail.getResourceId());
|
||||
ApiScenario apiScenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
|
||||
|
||||
// 独立报告,执行到当前任务时初始化报告
|
||||
String reportId = initScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, queue.getUserId()).getApiScenarioReportId();
|
||||
|
||||
TaskRequestDTO taskRequest = getTaskRequestDTO(apiScenario.getProjectId(), queue.getRunModeConfig());
|
||||
TaskItem taskItem = apiExecuteService.getTaskItem(reportId, queueDetail.getResourceId());
|
||||
taskRequest.setTaskItem(taskItem);
|
||||
taskRequest.getTaskInfo().setQueueId(queue.getQueueId());
|
||||
|
||||
apiExecuteService.execute(taskRequest);
|
||||
}
|
||||
|
||||
private TaskRequestDTO getTaskRequestDTO(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskRequestDTO taskRequest = new TaskRequestDTO();
|
||||
TaskInfo taskInfo = getTaskInfo(projectId, runModeConfig);
|
||||
taskRequest.setTaskInfo(taskInfo);
|
||||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskBatchRequestDTO getTaskBatchRequestDTO(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskBatchRequestDTO taskRequest = new TaskBatchRequestDTO();
|
||||
TaskInfo taskInfo = getTaskInfo(projectId, runModeConfig);
|
||||
taskRequest.setTaskInfo(taskInfo);
|
||||
return taskRequest;
|
||||
}
|
||||
|
||||
private TaskInfo getTaskInfo(String projectId, ApiRunModeConfigDTO runModeConfig) {
|
||||
TaskInfo taskInfo = apiScenarioBatchRunService.getTaskInfo(projectId, runModeConfig);
|
||||
taskInfo.setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
|
||||
return taskInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预生成用例的执行报告
|
||||
*
|
||||
* @param runModeConfig
|
||||
* @param apiScenario
|
||||
* @return
|
||||
*/
|
||||
public ApiScenarioRecord initScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenario testPlanApiScenario,
|
||||
ApiScenario apiScenario, String userId) {
|
||||
// 初始化报告
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, testPlanApiScenario, apiScenario, userId);
|
||||
apiScenarioReport.setId(IDGenerator.nextStr());
|
||||
// 创建报告和用例的关联关系
|
||||
ApiScenarioRecord apiScenarioRecord = apiScenarioRunService.getApiScenarioRecord(apiScenario, apiScenarioReport);
|
||||
apiScenarioReportService.insertApiScenarioReport(List.of(apiScenarioReport), List.of(apiScenarioRecord));
|
||||
return apiScenarioRecord;
|
||||
}
|
||||
|
||||
public String getEnvId(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenario testPlanApiScenario) {
|
||||
return StringUtils.isBlank(runModeConfig.getEnvironmentId()) ? testPlanApiScenario.getEnvironmentId() : runModeConfig.getEnvironmentId();
|
||||
}
|
||||
|
||||
private ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, TestPlanApiScenario testPlanApiScenario, ApiScenario apiScenario, String userId) {
|
||||
ApiScenarioReport apiScenarioReport = getScenarioReport(runModeConfig, userId);
|
||||
apiScenarioReport.setEnvironmentId(apiScenarioRunService.getEnvId(runModeConfig, apiScenario));
|
||||
apiScenarioReport.setName(apiScenario.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
|
||||
apiScenarioReport.setProjectId(apiScenario.getProjectId());
|
||||
apiScenarioReport.setTriggerMode(TaskTriggerMode.BATCH.name());
|
||||
apiScenarioReport.setTestPlanScenarioId(testPlanApiScenario.getId());
|
||||
apiScenarioReport.setEnvironmentId(getEnvId(runModeConfig, testPlanApiScenario));
|
||||
return apiScenarioReport;
|
||||
}
|
||||
|
||||
public ApiScenarioReport getScenarioReport(ApiRunModeConfigDTO runModeConfig, String userId) {
|
||||
ApiScenarioReport apiScenarioReport = apiScenarioRunService.getScenarioReport(userId);
|
||||
apiScenarioReport.setEnvironmentId(runModeConfig.getEnvironmentId());
|
||||
apiScenarioReport.setRunMode(runModeConfig.getRunMode());
|
||||
apiScenarioReport.setPoolId(runModeConfig.getPoolId());
|
||||
apiScenarioReport.setTriggerMode(TaskTriggerMode.BATCH.name());
|
||||
return apiScenarioReport;
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import io.metersphere.api.constants.ApiDefinitionStatus;
|
|||
import io.metersphere.api.controller.result.ApiResultCode;
|
||||
import io.metersphere.api.domain.ApiDefinition;
|
||||
import io.metersphere.api.domain.ApiTestCase;
|
||||
import io.metersphere.api.dto.ApiRunModeRequest;
|
||||
import io.metersphere.api.dto.definition.ApiDefinitionAddRequest;
|
||||
import io.metersphere.api.dto.definition.ApiTestCaseAddRequest;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
|
@ -21,6 +22,7 @@ import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
|||
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
|
||||
import io.metersphere.plan.service.TestPlanApiCaseService;
|
||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
|
||||
import io.metersphere.sdk.dto.api.task.TaskItem;
|
||||
|
@ -56,6 +58,7 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
|
|||
public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "batch/update/executor";
|
||||
private static final String URL_POST_RESOURCE_API_CASE_SORT = "/sort";
|
||||
public static final String RUN = "run/{0}";
|
||||
public static final String BATCH_RUN = "batch/run";
|
||||
public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}";
|
||||
|
||||
@Resource
|
||||
|
@ -274,6 +277,35 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.TEST_PLAN_READ_EXECUTE, RUN, testPlanApiCase.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void batchRun() throws Exception {
|
||||
TestPlanApiCaseBatchRunRequest request = new TestPlanApiCaseBatchRunRequest();
|
||||
request.setSelectIds(List.of(testPlanApiCase.getId()));
|
||||
request.setTestPlanId(testPlanApiCase.getTestPlanId());
|
||||
ApiRunModeRequest apiRunModeRequest = new ApiRunModeRequest();
|
||||
apiRunModeRequest.setRunMode(ApiBatchRunMode.PARALLEL.name());
|
||||
apiRunModeRequest.setStopOnFailure(false);
|
||||
apiRunModeRequest.setPoolId("poolId");
|
||||
request.setRunModeConfig(apiRunModeRequest);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
request.setProtocols(List.of("HTTP"));
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setIntegratedReport(false);
|
||||
apiRunModeRequest.setStopOnFailure(true);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setRunMode(ApiBatchRunMode.SERIAL.name());
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setIntegratedReport(true);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
// @@校验权限
|
||||
requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_EXECUTE, BATCH_RUN, request);
|
||||
}
|
||||
|
||||
public ApiTestCase initApiData() {
|
||||
ApiDefinitionAddRequest apiDefinitionAddRequest = createApiDefinitionAddRequest();
|
||||
MsHTTPElement msHttpElement = new MsHTTPElement();
|
||||
|
|
|
@ -5,17 +5,16 @@ import io.metersphere.api.constants.ApiScenarioStepRefType;
|
|||
import io.metersphere.api.constants.ApiScenarioStepType;
|
||||
import io.metersphere.api.controller.result.ApiResultCode;
|
||||
import io.metersphere.api.domain.ApiScenario;
|
||||
import io.metersphere.api.dto.ApiRunModeRequest;
|
||||
import io.metersphere.api.dto.assertion.MsAssertionConfig;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.dto.request.http.body.RawBody;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioAddRequest;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioOtherConfig;
|
||||
import io.metersphere.api.dto.scenario.*;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioBatchRunRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioTreeRequest;
|
||||
|
@ -24,7 +23,9 @@ import io.metersphere.plan.service.TestPlanApiScenarioService;
|
|||
import io.metersphere.project.api.assertion.MsResponseCodeAssertion;
|
||||
import io.metersphere.project.api.assertion.MsScriptAssertion;
|
||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.MsAssertionCondition;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
|
||||
import io.metersphere.sdk.dto.api.task.TaskItem;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
|
@ -40,10 +41,7 @@ import org.springframework.test.context.jdbc.SqlConfig;
|
|||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
|
||||
|
||||
|
@ -58,6 +56,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
public static final String API_SCENARIO_PAGE = "page";
|
||||
public static final String API_SCENARIO_TREE_COUNT = "module/count";
|
||||
public static final String API_SCENARIO_TREE = "tree";
|
||||
public static final String BATCH_RUN = "batch/run";
|
||||
|
||||
@Resource
|
||||
private TestPlanApiScenarioService testPlanApiScenarioService;
|
||||
|
@ -105,6 +104,40 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
taskItem.setReportId("reportId");
|
||||
request.setTaskItem(taskItem);
|
||||
testPlanApiScenarioService.getRunScript(request);
|
||||
|
||||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.TEST_PLAN_READ_EXECUTE, RUN, testPlanApiScenario.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void batchRun() throws Exception {
|
||||
mockPost("/api/batch/run", "");
|
||||
|
||||
TestPlanApiScenarioBatchRunRequest request = new TestPlanApiScenarioBatchRunRequest();
|
||||
request.setSelectIds(List.of(testPlanApiScenario.getId()));
|
||||
request.setTestPlanId(testPlanApiScenario.getTestPlanId());
|
||||
ApiRunModeRequest apiRunModeRequest = new ApiRunModeRequest();
|
||||
apiRunModeRequest.setRunMode(ApiBatchRunMode.PARALLEL.name());
|
||||
apiRunModeRequest.setIntegratedReport(true);
|
||||
apiRunModeRequest.setStopOnFailure(false);
|
||||
apiRunModeRequest.setIntegratedReportName("aaaa");
|
||||
apiRunModeRequest.setPoolId("poolId");
|
||||
request.setRunModeConfig(apiRunModeRequest);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setIntegratedReport(false);
|
||||
apiRunModeRequest.setStopOnFailure(true);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setRunMode(ApiBatchRunMode.SERIAL.name());
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
apiRunModeRequest.setIntegratedReport(true);
|
||||
this.requestPostWithOk(BATCH_RUN, request);
|
||||
|
||||
// @@校验权限
|
||||
requestPostPermissionTest(PermissionConstants.TEST_PLAN_READ_EXECUTE, BATCH_RUN, request);
|
||||
}
|
||||
|
||||
public ApiScenario initApiData() {
|
||||
|
|
Loading…
Reference in New Issue