fix(测试跟踪): 修复执行测试计划时含有失败用例不会发送通知的问题

--bug=1013981 --user=宋天阳
【消息设置】测试计划的“执行成功”和“执行完成”是一个逻辑都是指测试计划执行完成就会收到消息通知
https://www.tapd.cn/55049933/s/1179702
This commit is contained in:
song-tianyang 2022-06-13 16:51:28 +08:00 committed by TIanyang
parent 95f6c458fe
commit 62578975e3
2 changed files with 136 additions and 42 deletions

View File

@ -3,11 +3,13 @@ package io.metersphere.track.service;
import io.metersphere.api.service.ShareInfoService;
import io.metersphere.base.domain.TestPlan;
import io.metersphere.base.domain.TestPlanReport;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.constants.ReportTriggerMode;
import io.metersphere.commons.constants.TestPlanReportStatus;
import io.metersphere.base.domain.TestPlanReportContentWithBLOBs;
import io.metersphere.base.domain.TestPlanWithBLOBs;
import io.metersphere.base.mapper.TestPlanMapper;
import io.metersphere.commons.constants.*;
import io.metersphere.commons.utils.BeanUtils;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.dto.BaseSystemConfigDTO;
import io.metersphere.dto.UserDTO;
import io.metersphere.i18n.Translator;
@ -36,11 +38,44 @@ public class TestPlanMessageService {
private ProjectService projectService;
@Lazy
@Resource
private TestPlanService testPlanService;
private TestPlanService testPlanService;
@Resource
private UserService userService;
@Resource
private ShareInfoService shareInfoService;
@Resource
private TestPlanMapper testPlanMapper;
@Lazy
@Resource
private TestPlanReportService testPlanReportService;
@Async
public void checkTestPlanStatusAndSendMessage(TestPlanReport report, TestPlanReportContentWithBLOBs testPlanReportContent, boolean sendMessage) {
if (testPlanReportContent != null) {
report = testPlanReportService.checkTestPlanReportHasErrorCase(report, testPlanReportContent);
}
if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting()) {
//更新TestPlan状态为完成
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(report.getTestPlanId());
if (testPlan != null && !StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Completed.name())) {
testPlan.setStatus(TestPlanStatus.Completed.name());
testPlanService.editTestPlan(testPlan);
}
try {
if (sendMessage && testPlan != null && StringUtils.equalsAny(report.getTriggerMode(),
ReportTriggerMode.MANUAL.name(),
ReportTriggerMode.API.name(),
ReportTriggerMode.SCHEDULE.name()) && !StringUtils.equalsIgnoreCase(report.getStatus(), ExecuteResult.TEST_PLAN_RUNNING.toString())
) {
//发送通知
this.sendMessage(testPlan, report, testPlan.getProjectId());
}
} catch (Exception e) {
LogUtil.error(e);
}
}
}
@Async
public void sendMessage(TestPlan testPlan, TestPlanReport testPlanReport, String projectId) {

View File

@ -431,8 +431,9 @@ public class TestPlanReportService {
if (testPlanReport != null && StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), "stopped")) {
return testPlanReport;
}
boolean isSendMessage = false;
TestPlanReportContentWithBLOBs content = null;
if (testPlanReport != null) {
boolean isSendMessage = false;
if (StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), ExecuteResult.TEST_PLAN_RUNNING.toString())) {
isSendMessage = true;
}
@ -454,11 +455,9 @@ public class TestPlanReportService {
TestPlanReportContentExample contentExample = new TestPlanReportContentExample();
contentExample.createCriteria().andTestPlanReportIdEqualTo(testPlanReportId);
List<TestPlanReportContentWithBLOBs> contents = testPlanReportContentMapper.selectByExampleWithBLOBs(contentExample);
TestPlanReportContentWithBLOBs content = null;
if (CollectionUtils.isNotEmpty(contents)) {
content = contents.get(0);
}
boolean hasErrorCase = false;
if (content != null) {
//更新content表对结束日期
if (!StringUtils.equalsAnyIgnoreCase(testPlanReport.getStatus(), APITestStatus.Rerunning.name())) {
@ -469,11 +468,7 @@ public class TestPlanReportService {
}
//计算测试计划状态
if (StringUtils.equalsIgnoreCase(status, TestPlanReportStatus.COMPLETED.name())) {
if (hasErrorCase) {
testPlanReport.setStatus(TestPlanReportStatus.FAILED.name());
} else {
testPlanReport.setStatus(TestPlanReportStatus.SUCCESS.name());
}
testPlanReport.setStatus(TestPlanReportStatus.SUCCESS.name());
} else {
testPlanReport.setStatus(status);
}
@ -508,9 +503,9 @@ public class TestPlanReportService {
testPlanService.runPlan(runRequest);
}
testPlanReportMapper.updateByPrimaryKey(testPlanReport);
//发送通知
this.checkTestPlanStatusAndSendMessage(testPlanReport, isSendMessage);
}
//发送通知
testPlanMessageService.checkTestPlanStatusAndSendMessage(testPlanReport, content, isSendMessage);
return testPlanReport;
}
@ -567,7 +562,7 @@ public class TestPlanReportService {
String testPlanStatus = this.getTestPlanReportStatus(testPlanReport, reportDTO);
testPlanReport.setStatus(testPlanStatus);
testPlanReportMapper.updateByPrimaryKey(testPlanReport);
this.checkTestPlanStatusAndSendMessage(testPlanReport, false);
testPlanMessageService.checkTestPlanStatusAndSendMessage(testPlanReport, null, false);
}
public TestPlanReportContentWithBLOBs parseReportDaoToReportContent(TestPlanSimpleReportDTO reportDTO, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) {
@ -671,29 +666,6 @@ public class TestPlanReportService {
return status;
}
public void checkTestPlanStatusAndSendMessage(TestPlanReport report, boolean sendMessage) {
if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting()) {
//更新TestPlan状态为完成
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(report.getTestPlanId());
if (testPlan != null && !StringUtils.equals(testPlan.getStatus(), TestPlanStatus.Completed.name())) {
testPlan.setStatus(TestPlanStatus.Completed.name());
testPlanService.editTestPlan(testPlan);
}
try {
if (sendMessage && testPlan != null && StringUtils.equalsAny(report.getTriggerMode(),
ReportTriggerMode.MANUAL.name(),
ReportTriggerMode.API.name(),
ReportTriggerMode.SCHEDULE.name()) && !StringUtils.equalsIgnoreCase(report.getStatus(), ExecuteResult.TEST_PLAN_RUNNING.toString())
) {
//发送通知
testPlanMessageService.sendMessage(testPlan, report, testPlan.getProjectId());
}
} catch (Exception e) {
LogUtil.error(e);
}
}
}
public TestPlanReport getTestPlanReport(String planId) {
return testPlanReportMapper.selectByPrimaryKey(planId);
}
@ -958,8 +930,8 @@ public class TestPlanReportService {
Map<String, String> testPlanApiCaseIdAndReportIdMap = new LinkedHashMap<>();
Map<String, String> testPlanScenarioIdAndReportIdMap = new LinkedHashMap<>();
Map<String, String> testPlanLoadCaseIdAndReportIdMap = new LinkedHashMap<>();
Map<String,TestPlanFailureApiDTO> apiCaseInfoDTOMap = new LinkedHashMap<>();
Map<String,TestPlanFailureScenarioDTO> scenarioInfoDTOMap = new LinkedHashMap<>();
Map<String, TestPlanFailureApiDTO> apiCaseInfoDTOMap = new LinkedHashMap<>();
Map<String, TestPlanFailureScenarioDTO> scenarioInfoDTOMap = new LinkedHashMap<>();
if (testPlanReportContentWithBLOBs != null) {
if (StringUtils.isNotEmpty(testPlanReportContentWithBLOBs.getPlanApiCaseReportStruct())) {
@ -976,7 +948,7 @@ public class TestPlanReportService {
} else {
for (TestPlanFailureApiDTO item : apiCaseInfoDTOList) {
testPlanApiCaseIdAndReportIdMap.put(item.getId(), item.getReportId());
apiCaseInfoDTOMap.put(item.getId(),item);
apiCaseInfoDTOMap.put(item.getId(), item);
}
}
}
@ -994,7 +966,7 @@ public class TestPlanReportService {
} else {
for (TestPlanFailureScenarioDTO item : scenarioInfoDTOList) {
testPlanScenarioIdAndReportIdMap.put(item.getId(), item.getReportId());
scenarioInfoDTOMap.put(item.getId(),item);
scenarioInfoDTOMap.put(item.getId(), item);
}
}
}
@ -1032,4 +1004,91 @@ public class TestPlanReportService {
testPlanReportMapper.updateByPrimaryKey(testPlanReport);
}
}
public TestPlanReport checkTestPlanReportHasErrorCase(TestPlanReport report, TestPlanReportContentWithBLOBs testPlanReportContent) {
if (testPlanReportContent != null) {
boolean hasErrorCase = this.isTestPlanReportHasErrorCase(testPlanReportContent);
if (hasErrorCase) {
report.setStatus(TestPlanReportStatus.FAILED.name());
} else {
report.setStatus(TestPlanReportStatus.SUCCESS.name());
}
testPlanReportMapper.updateByPrimaryKeySelective(report);
}
return report;
}
private boolean isTestPlanReportHasErrorCase(TestPlanReportContentWithBLOBs content) {
//更新测试计划里用例的执行结果并检查是否有错误用例
boolean hasErrorCase = false;
if (content != null) {
//更新接口用例场景用例的最终执行状态
if (!hasErrorCase && StringUtils.isNotEmpty(content.getPlanApiCaseReportStruct())) {
try {
List<TestPlanFailureApiDTO> apiTestCases = JSONArray.parseArray(content.getPlanApiCaseReportStruct(), TestPlanFailureApiDTO.class);
List<String> reportIdList = new ArrayList<>();
apiTestCases.forEach(item -> {
if (StringUtils.isNotEmpty(item.getReportId())) {
reportIdList.add(item.getReportId());
}
});
Map<String, String> reportResult = apiDefinitionExecResultService.selectReportResultByReportIds(reportIdList);
String defaultStatus = "error";
for (TestPlanFailureApiDTO dto : apiTestCases) {
String reportId = dto.getReportId();
if (StringUtils.isEmpty(reportId)) {
dto.setExecResult(defaultStatus);
} else {
String execStatus = reportResult.get(reportId);
if (execStatus == null) {
execStatus = defaultStatus;
}
dto.setExecResult(execStatus);
}
if (!StringUtils.equalsAnyIgnoreCase(dto.getExecResult(), "success")) {
hasErrorCase = true;
}
}
} catch (Exception e) {
LogUtil.error("Parse test plan report api case error! ", e);
}
}
if (!hasErrorCase && StringUtils.isNotEmpty(content.getPlanScenarioReportStruct())) {
try {
List<TestPlanFailureScenarioDTO> scenarioCases = JSONArray.parseArray(content.getPlanScenarioReportStruct(), TestPlanFailureScenarioDTO.class);
List<String> reportIdList = new ArrayList<>();
scenarioCases.forEach(item -> {
if (StringUtils.isNotEmpty(item.getReportId())) {
reportIdList.add(item.getReportId());
}
});
String defaultStatus = "Fail";
Map<String, String> reportStatus = apiScenarioReportService.getReportStatusByReportIds(reportIdList);
for (TestPlanFailureScenarioDTO dto : scenarioCases) {
String reportId = dto.getReportId();
if (StringUtils.isNotEmpty(reportId)) {
String execStatus = reportStatus.get(reportId);
if (execStatus == null) {
execStatus = defaultStatus;
} else {
if (StringUtils.equalsIgnoreCase(execStatus, "Error")) {
execStatus = "Fail";
}
}
dto.setLastResult(execStatus);
dto.setStatus(execStatus);
if (!StringUtils.equalsAnyIgnoreCase(execStatus, "success")) {
hasErrorCase = true;
}
}
}
} catch (Exception e) {
LogUtil.error("Parse test plan report cenario case error!", e);
}
}
}
return hasErrorCase;
}
}