fix(测试跟踪): 优化测试计划执行方法,当测试计划内的自动化用例无法执行时,不会卡在running状态

--bug=1024782 --user=宋天阳
【测试跟踪】测试计划-关联的功能用例同步关联的接口场景没有环境-执行该计划未选环境时测试报告显示错误
https://www.tapd.cn/55049933/s/1354725
This commit is contained in:
song-tianyang 2023-03-23 11:19:33 +08:00 committed by 建国
parent c06205aacc
commit bd24753190
2 changed files with 36 additions and 9 deletions

View File

@ -60,7 +60,7 @@ public class TestPlanTestJob extends MsScheduleJob {
// 定时任务指定调用微服务的user // 定时任务指定调用微服务的user
HttpHeaderUtils.runAsUser(baseUserService.getUserDTO(runUserId)); HttpHeaderUtils.runAsUser(baseUserService.getUserDTO(runUserId));
testPlanService.run(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(), null, ExecutionWay.RUN.name(), config); testPlanService.runTestPlan(runResourceId, runProjectId, runUserId, ReportTriggerMode.SCHEDULE.name(), null, ExecutionWay.RUN.name(), config);
HttpHeaderUtils.clearUser(); HttpHeaderUtils.clearUser();
} }

View File

@ -69,6 +69,7 @@ import org.mybatis.spring.SqlSessionUtils;
import org.quartz.*; import org.quartz.*;
import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Lazy;
import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -838,7 +839,7 @@ public class TestPlanService {
return testPlanReportService.genTestPlanReportBySchedule(planReportId, planId, userId, triggerMode, runModeConfigDTO); return testPlanReportService.genTestPlanReportBySchedule(planReportId, planId, userId, triggerMode, runModeConfigDTO);
} }
public String run(String testPlanId, String projectId, String userId, String triggerMode, String planReportId, String executionWay, String apiRunConfig) { public String runTestPlan(String testPlanId, String projectId, String userId, String triggerMode, String planReportId, String executionWay, String apiRunConfig) {
RunModeConfigDTO runModeConfig = null; RunModeConfigDTO runModeConfig = null;
try { try {
runModeConfig = JSON.parseObject(apiRunConfig, RunModeConfigDTO.class); runModeConfig = JSON.parseObject(apiRunConfig, RunModeConfigDTO.class);
@ -920,13 +921,17 @@ public class TestPlanService {
LogUtil.error("测试计划执行查询UI用例失败!", e); LogUtil.error("测试计划执行查询UI用例失败!", e);
} }
} }
boolean haveApiCaseExec = false, haveScenarioCaseExec = false, haveLoadCaseExec = false, haveUICaseExec = false;
if (CollectionUtils.isNotEmpty(apiTestCases)) { if (CollectionUtils.isNotEmpty(apiTestCases)) {
//执行接口案例任务 //执行接口案例任务
LoggerUtil.info("开始执行测试计划接口用例 " + planReportId); LoggerUtil.info("开始执行测试计划接口用例 " + planReportId);
try { try {
Map<String, String> apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, testPlanId, runModeConfig); Map<String, String> apiCaseReportMap = this.executeApiTestCase(triggerMode, planReportId, userId, testPlanId, runModeConfig);
for (TestPlanApiDTO dto : apiTestCases) { if (MapUtils.isNotEmpty(apiCaseReportMap)) {
dto.setReportId(apiCaseReportMap.get(dto.getId())); haveApiCaseExec = true;
for (TestPlanApiDTO dto : apiTestCases) {
dto.setReportId(apiCaseReportMap.get(dto.getId()));
}
} }
} catch (Exception e) { } catch (Exception e) {
apiTestCases = null; apiTestCases = null;
@ -938,8 +943,11 @@ public class TestPlanService {
LoggerUtil.info("开始执行测试计划场景用例 " + planReportId); LoggerUtil.info("开始执行测试计划场景用例 " + planReportId);
try { try {
Map<String, String> scenarioReportMap = this.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap()); Map<String, String> scenarioReportMap = this.executeScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getPlanScenarioIdMap());
for (TestPlanScenarioDTO dto : scenarioCases) { if (MapUtils.isNotEmpty(scenarioReportMap)) {
dto.setReportId(scenarioReportMap.get(dto.getId())); haveScenarioCaseExec = true;
for (TestPlanScenarioDTO dto : scenarioCases) {
dto.setReportId(scenarioReportMap.get(dto.getId()));
}
} }
} catch (Exception e) { } catch (Exception e) {
scenarioCases = null; scenarioCases = null;
@ -952,6 +960,9 @@ public class TestPlanService {
LoggerUtil.info("开始执行测试计划性能用例 " + planReportId); LoggerUtil.info("开始执行测试计划性能用例 " + planReportId);
try { try {
loadCaseReportMap = perfExecService.executeLoadCase(planReportId, runModeConfig, transformationPerfTriggerMode(triggerMode), reportInfoDTO.getPerformanceIdMap()); loadCaseReportMap = perfExecService.executeLoadCase(planReportId, runModeConfig, transformationPerfTriggerMode(triggerMode), reportInfoDTO.getPerformanceIdMap());
if (MapUtils.isNotEmpty(loadCaseReportMap)) {
haveLoadCaseExec = true;
}
} catch (Exception e) { } catch (Exception e) {
LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划性能用例失败! ", e); LoggerUtil.info("测试报告" + planReportId + "本次执行测试计划性能用例失败! ", e);
} }
@ -962,8 +973,11 @@ public class TestPlanService {
LoggerUtil.info("开始执行测试计划 UI 场景用例 " + planReportId); LoggerUtil.info("开始执行测试计划 UI 场景用例 " + planReportId);
try { try {
Map<String, String> uiScenarioReportMap = this.executeUiScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getUiScenarioIdMap()); Map<String, String> uiScenarioReportMap = this.executeUiScenarioCase(planReportId, testPlanId, projectId, runModeConfig, triggerMode, userId, reportInfoDTO.getUiScenarioIdMap());
for (TestPlanUiScenarioDTO dto : uiScenarios) { if (MapUtils.isNotEmpty(uiScenarioReportMap)) {
dto.setReportId(uiScenarioReportMap.get(dto.getId())); haveUICaseExec = true;
for (TestPlanUiScenarioDTO dto : uiScenarios) {
dto.setReportId(uiScenarioReportMap.get(dto.getId()));
}
} }
} catch (Exception e) { } catch (Exception e) {
uiScenarios = null; uiScenarios = null;
@ -973,9 +987,22 @@ public class TestPlanService {
LoggerUtil.info("开始生成测试计划报告内容 " + planReportId); LoggerUtil.info("开始生成测试计划报告内容 " + planReportId);
testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiTestCases, scenarioCases, uiScenarios, loadCaseReportMap); testPlanReportService.createTestPlanReportContentReportIds(planReportId, apiTestCases, scenarioCases, uiScenarios, loadCaseReportMap);
if (!haveApiCaseExec && !haveScenarioCaseExec && !haveLoadCaseExec && !haveUICaseExec) {
/**
*如果没有执行自动化用例结束测试计划的执行
* 使用异步操作的方式是为了更早的将执行信息回馈给前台
* 不为前台直接返回无法执行的报错是考虑到测试计划内会有功能用例issue等信息可以进行统计
*/
this.syncFinishTestPlanExecute(planReportId);
}
return planReportId; return planReportId;
} }
@Async
void syncFinishTestPlanExecute(String planReportId) {
testPlanReportService.testPlanExecuteOver(planReportId, TestPlanReportStatus.COMPLETED.name());
}
public void verifyPool(String projectId, RunModeConfigDTO runConfig) { public void verifyPool(String projectId, RunModeConfigDTO runConfig) {
// 检查是否禁用了本地执行 // 检查是否禁用了本地执行
apiPoolDebugService.verifyPool(projectId, runConfig); apiPoolDebugService.verifyPool(projectId, runConfig);
@ -1682,7 +1709,7 @@ public class TestPlanService {
runModeConfig.setTestPlanDefaultEnvMap(testplanRunRequest.getTestPlanDefaultEnvMap()); runModeConfig.setTestPlanDefaultEnvMap(testplanRunRequest.getTestPlanDefaultEnvMap());
String apiRunConfig = JSON.toJSONString(runModeConfig); String apiRunConfig = JSON.toJSONString(runModeConfig);
return this.run(testPlanId, testplanRunRequest.getProjectId(), return this.runTestPlan(testPlanId, testplanRunRequest.getProjectId(),
testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getReportId(), testplanRunRequest.getExecutionWay(), apiRunConfig); testplanRunRequest.getUserId(), testplanRunRequest.getTriggerMode(), testplanRunRequest.getReportId(), testplanRunRequest.getExecutionWay(), apiRunConfig);
} }