refactor(测试计划): 优化测试计划执行完成之后的回调函数

优化测试计划执行完成之后的回调函数
This commit is contained in:
song-tianyang 2023-05-11 15:38:16 +08:00 committed by fit2-zhao
parent 22b2ef3e82
commit 47ad7a1c2a
3 changed files with 64 additions and 68 deletions

View File

@ -1,6 +1,9 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.ShareInfo;
import io.metersphere.base.domain.TestPlan;
import io.metersphere.base.domain.TestPlanReport;
import io.metersphere.base.domain.TestPlanReportContentWithBLOBs;
import io.metersphere.base.mapper.TestPlanMapper; import io.metersphere.base.mapper.TestPlanMapper;
import io.metersphere.commons.constants.*; import io.metersphere.commons.constants.*;
import io.metersphere.commons.utils.BeanUtils; import io.metersphere.commons.utils.BeanUtils;
@ -24,7 +27,10 @@ import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@ -45,25 +51,14 @@ public class TestPlanMessageService {
@Resource @Resource
private TestPlanReportService testPlanReportService; private TestPlanReportService testPlanReportService;
public static final Integer FULL_MARKS = 100;
@Async @Async
public void checkTestPlanStatusAndSendMessage(TestPlanReport report, TestPlanReportContentWithBLOBs testPlanReportContent, boolean sendMessage) { public void checkTestPlanStatusAndSendMessage(TestPlanReport report, TestPlanReportContentWithBLOBs testPlanReportContent, TestPlan testPlan, boolean sendMessage) {
if (report != null && testPlanReportContent != null) { if (report != null && testPlanReportContent != null) {
// 异步发送通知需要指定调用其他服务的user // 异步发送通知需要指定调用其他服务的user
HttpHeaderUtils.runAsUser(report.getCreator()); HttpHeaderUtils.runAsUser(report.getCreator());
try { try {
report = testPlanReportService.checkTestPlanReportHasErrorCase(report, testPlanReportContent); report = testPlanReportService.checkTestPlanReportHasErrorCase(report, testPlanReportContent);
if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting() && !report.getIsUiScenarioExecuting()) { if (!report.getIsApiCaseExecuting() && !report.getIsPerformanceExecuting() && !report.getIsScenarioExecuting() && !report.getIsUiScenarioExecuting()) {
//更新TestPlan状态为完成
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(report.getTestPlanId());
if (testPlan != null
&& !StringUtils.equalsAny(testPlan.getStatus(), TestPlanStatus.Completed.name(), TestPlanStatus.Finished.name())) {
testPlan.setStatus(calcTestPlanStatusWithPassRate(testPlan));
testPlanService.editTestPlan(testPlan);
}
if (sendMessage && testPlan != null && StringUtils.equalsAny(report.getTriggerMode(), if (sendMessage && testPlan != null && StringUtils.equalsAny(report.getTriggerMode(),
ReportTriggerMode.MANUAL.name(), ReportTriggerMode.MANUAL.name(),
ReportTriggerMode.API.name(), ReportTriggerMode.API.name(),
@ -82,40 +77,6 @@ public class TestPlanMessageService {
} }
} }
private String calcTestPlanStatusWithPassRate(TestPlanWithBLOBs testPlan) {
try {
// 计算通过率
TestPlanDTOWithMetric testPlanDTOWithMetric = BeanUtils.copyBean(new TestPlanDTOWithMetric(), testPlan);
testPlanService.calcTestPlanRate(Collections.singletonList(testPlanDTOWithMetric));
//测试进度
Double testRate = Optional.ofNullable(testPlanDTOWithMetric.getTestRate()).orElse(0.0);
//通过率
Double passRate = Optional.ofNullable(testPlanDTOWithMetric.getPassRate()).orElse(0.0);
// 已完成测试进度=100% 通过率=100%
if (testRate >= FULL_MARKS && passRate >= FULL_MARKS) {
return TestPlanStatus.Completed.name();
}
// 已结束超过了计划结束时间如有 测试进度=100% 通过率非100%
Long plannedEndTime = testPlan.getPlannedEndTime();
long currentTime = System.currentTimeMillis();
if (Objects.nonNull(plannedEndTime) && currentTime >= plannedEndTime) {
return TestPlanStatus.Finished.name();
}
if (testRate >= FULL_MARKS && passRate < FULL_MARKS) {
return TestPlanStatus.Finished.name();
}
} catch (Exception e) {
LogUtil.error("计算通过率失败!", e);
}
// 进行中0 < 测试进度 < 100%
return TestPlanStatus.Underway.name();
}
private void sendMessage(TestPlan testPlan, TestPlanReport testPlanReport, String projectId) { private void sendMessage(TestPlan testPlan, TestPlanReport testPlanReport, String projectId) {
assert testPlan != null; assert testPlan != null;
SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class); SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);

View File

@ -586,20 +586,25 @@ public class TestPlanReportService {
isSendMessage = true; isSendMessage = true;
} }
TestPlanReportContentWithBLOBs content = null; TestPlanReportContentWithBLOBs content = null;
TestPlanWithBLOBs testPlanWithBLOBs = null;
try { try {
HttpHeaderUtils.runAsUser(testPlanReport.getCreator()); HttpHeaderUtils.runAsUser(testPlanReport.getCreator());
boolean isRerunningTestPlan = BooleanUtils.isTrue(StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), APITestStatus.Rerunning.name())); boolean isRerunningTestPlan = BooleanUtils.isTrue(StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), APITestStatus.Rerunning.name()));
//测试计划报告结果数据初始化 //测试计划报告结果数据初始化
testPlanReport.setStatus(finishStatus); testPlanReport.setStatus(finishStatus);
//统计并保存报告
content = this.countAndSaveTestPlanReport(testPlanReport, isRerunningTestPlan); content = this.countAndSaveTestPlanReport(testPlanReport, isRerunningTestPlan);
this.setReportExecuteResult(testPlanReport, finishStatus); //更新测试计划的执行相关信息(状态执行率等
testPlanWithBLOBs = testPlanService.selectAndChangeTestPlanExecuteInfo(testPlanReport.getTestPlanId());
} catch (Exception e) { } catch (Exception e) {
testPlanReport.setStatus(finishStatus); testPlanReport.setStatus(finishStatus);
LogUtil.error("统计测试计划状态失败!", e); LogUtil.error("统计测试计划状态失败!", e);
} finally { } finally {
HttpHeaderUtils.clearUser(); HttpHeaderUtils.clearUser();
testPlanReportMapper.updateByPrimaryKey(testPlanReport); testPlanReportMapper.updateByPrimaryKey(testPlanReport);
testPlanMessageService.checkTestPlanStatusAndSendMessage(testPlanReport, content, isSendMessage); if (testPlanWithBLOBs != null) {
testPlanMessageService.checkTestPlanStatusAndSendMessage(testPlanReport, content, testPlanWithBLOBs, isSendMessage);
}
this.executeTestPlanByQueue(testPlanReportId); this.executeTestPlanByQueue(testPlanReportId);
} }
} }
@ -617,17 +622,6 @@ public class TestPlanReportService {
} }
} }
/**
* 测试计划报告设置最终执行状态
*/
private void setReportExecuteResult(TestPlanReport testPlanReport, String finishStatus) {
//计算测试计划状态
testPlanReport.setStatus(StringUtils.equalsIgnoreCase(finishStatus, TestPlanReportStatus.COMPLETED.name()) ?
TestPlanReportStatus.SUCCESS.name() : finishStatus);
//检查更新测试计划状态
testPlanService.checkTestPlanStatusWhenExecuteOver(testPlanReport.getTestPlanId());
}
/** /**
* 统计测试计划报告信息 * 统计测试计划报告信息
*/ */

View File

@ -293,13 +293,7 @@ public class TestPlanService {
&& res.getActualStartTime() == null) { && res.getActualStartTime() == null) {
testPlan.setActualStartTime(System.currentTimeMillis()); testPlan.setActualStartTime(System.currentTimeMillis());
} }
testPlanMapper.updateByPrimaryKeyWithBLOBs(testPlan);
if (testPlan.getName() == null) {// 若是点击该测试计划则仅更新了updateTime其它字段全为null使用updateByPrimaryKeySelective
testPlanMapper.updateByPrimaryKeySelective(testPlan);
} else { // 有修改字段的调用为保证将某些时间置null的情况使用updateByPrimaryKey
baseScheduleService.updateNameByResourceID(testPlan.getId(), testPlan.getName());// 同步更新该测试的定时任务的name
testPlanMapper.updateByPrimaryKeyWithBLOBs(testPlan); // 更新
}
return testPlanMapper.selectByPrimaryKey(testPlan.getId()); return testPlanMapper.selectByPrimaryKey(testPlan.getId());
} }
@ -2300,4 +2294,51 @@ public class TestPlanService {
} }
return testPlanExecuteService.runTestPlan(testPlanId, projectId, userId, triggerMode, planReportId, executionWay, apiRunConfig); return testPlanExecuteService.runTestPlan(testPlanId, projectId, userId, triggerMode, planReportId, executionWay, apiRunConfig);
} }
public TestPlanWithBLOBs selectAndChangeTestPlanExecuteInfo(String testPlanId) {
//更新TestPlan状态为完成
TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanId);
if (testPlan != null
&& !StringUtils.equalsAny(testPlan.getStatus(), TestPlanStatus.Completed.name(), TestPlanStatus.Finished.name())) {
testPlan.setStatus(calcTestPlanStatusWithPassRate(testPlan));
this.editTestPlan(testPlan);
}
return testPlan;
}
private String calcTestPlanStatusWithPassRate(TestPlanWithBLOBs testPlan) {
try {
int fullMarks = 100;
// 计算通过率
TestPlanDTOWithMetric testPlanDTOWithMetric = BeanUtils.copyBean(new TestPlanDTOWithMetric(), testPlan);
testPlanService.calcTestPlanRate(Collections.singletonList(testPlanDTOWithMetric));
//测试进度
Double testRate = Optional.ofNullable(testPlanDTOWithMetric.getTestRate()).orElse(0.0);
//通过率
Double passRate = Optional.ofNullable(testPlanDTOWithMetric.getPassRate()).orElse(0.0);
// 已完成测试进度=100% 通过率=100%
if (testRate >= fullMarks && passRate >= fullMarks) {
return TestPlanStatus.Completed.name();
}
// 已结束超过了计划结束时间如有 测试进度=100% 通过率非100%
Long plannedEndTime = testPlan.getPlannedEndTime();
long currentTime = System.currentTimeMillis();
if (Objects.nonNull(plannedEndTime) && currentTime >= plannedEndTime) {
return TestPlanStatus.Finished.name();
}
if (testRate >= fullMarks && passRate < fullMarks) {
return TestPlanStatus.Finished.name();
}
} catch (Exception e) {
LogUtil.error("计算通过率失败!", e);
}
// 进行中0 < 测试进度 < 100%
return TestPlanStatus.Underway.name();
}
} }