From 37dd2127e58c4449aaa7ec3e66a38a686dba8b7f Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Tue, 28 Mar 2023 11:42:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B5=8B=E8=AF=95=E6=8A=A5=E5=91=8A=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=95=B0=E6=8D=AE=E7=9A=84=E5=A4=84=E7=90=86=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1024864 --user=宋天阳 【测试跟踪】计划执行中-test-track异常启动-报告Completed后-在计划中增加用例-该报告的通过率会重新计算 https://www.tapd.cn/55049933/s/1356453 --bug=1024861 --user=宋天阳 【测试跟踪】测试计划执行中-查看报告-结束时间显示为开始时间 https://www.tapd.cn/55049933/s/1356455 --bug=1024863 --user=宋天阳 【测试跟踪】执行测试计划中test-track服务重启-报告结束时间显示为开始时间 https://www.tapd.cn/55049933/s/1356456 --- .../ext/ExtTestPlanReportContentMapper.java | 2 + .../ext/ExtTestPlanReportContentMapper.xml | 6 +++ .../plan/dto/TestPlanReportDataStruct.java | 53 +++++++++++++++++++ .../plan/service/TestPlanReportService.java | 41 ++++++-------- .../plan/service/TestPlanService.java | 19 +++++-- 5 files changed, 90 insertions(+), 31 deletions(-) diff --git a/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.java b/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.java index c7d6d95b1d..7ad8d19676 100644 --- a/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.java +++ b/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.java @@ -14,4 +14,6 @@ public interface ExtTestPlanReportContentMapper { boolean hasRunningReport(@Param("planId") String planId); boolean hasRunningReportByPlanIds(@Param("planIds") List planIds); + + boolean isApiBasicCountIsNull(String testPlanReportId); } diff --git a/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.xml b/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.xml index e3bec52a18..6efd6bf792 100644 --- a/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.xml +++ b/test-track/backend/src/main/java/io/metersphere/base/mapper/ext/ExtTestPlanReportContentMapper.xml @@ -37,4 +37,10 @@ and status = 'RUNNING' order by create_time desc limit 1; + + + diff --git a/test-track/backend/src/main/java/io/metersphere/plan/dto/TestPlanReportDataStruct.java b/test-track/backend/src/main/java/io/metersphere/plan/dto/TestPlanReportDataStruct.java index ba828572c7..467a3ac67a 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/dto/TestPlanReportDataStruct.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/dto/TestPlanReportDataStruct.java @@ -2,10 +2,14 @@ package io.metersphere.plan.dto; import io.metersphere.base.domain.TestPlanReportContent; +import io.metersphere.commons.constants.PerformanceTestStatus; import io.metersphere.dto.*; +import io.metersphere.plan.constant.ApiReportStatus; import io.metersphere.xpack.track.dto.IssuesDao; import lombok.Getter; import lombok.Setter; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import java.util.List; import java.util.Map; @@ -62,4 +66,53 @@ public class TestPlanReportDataStruct extends TestPlanReportContent { List uiAllCases; List uiFailureCases; + + public boolean hasRunningCase() { + //判断是否含有运行中的用例。 方法内针对集合不开流是为了不影响后续业务中使用stream + if (CollectionUtils.isNotEmpty(apiAllCases)) { + List runningCaseList = + apiAllCases.stream().filter( + dto -> StringUtils.equalsAnyIgnoreCase(dto.getExecResult(), + ApiReportStatus.PENDING.name(), + ApiReportStatus.RERUNNING.name(), + ApiReportStatus.RUNNING.name())).toList(); + if (runningCaseList.size() > 0) { + return true; + } + } + if (CollectionUtils.isNotEmpty(scenarioAllCases)) { + List runningCaseList = + scenarioAllCases.stream().filter( + dto -> StringUtils.equalsAnyIgnoreCase(dto.getLastResult(), + ApiReportStatus.PENDING.name(), + ApiReportStatus.RERUNNING.name(), + ApiReportStatus.RUNNING.name())).toList(); + if (runningCaseList.size() > 0) { + return true; + } + } + if (CollectionUtils.isNotEmpty(loadAllCases)) { + List runningCaseList = + loadAllCases.stream().filter( + dto -> StringUtils.equalsAnyIgnoreCase(dto.getStatus(), + PerformanceTestStatus.Starting.name(), + PerformanceTestStatus.Running.name(), + PerformanceTestStatus.Reporting.name())).toList(); + if (runningCaseList.size() > 0) { + return true; + } + } + if (CollectionUtils.isNotEmpty(uiAllCases)) { + List runningCaseList = + uiAllCases.stream().filter( + dto -> StringUtils.equalsAnyIgnoreCase(dto.getLastResult(), + ApiReportStatus.PENDING.name(), + ApiReportStatus.RERUNNING.name(), + ApiReportStatus.RUNNING.name())).toList(); + if (runningCaseList.size() > 0) { + return true; + } + } + return false; + } } diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java index 510408c5b8..c8fae7154b 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanReportService.java @@ -24,7 +24,6 @@ import io.metersphere.plan.request.performance.LoadPlanReportDTO; import io.metersphere.plan.request.ui.TestPlanUiExecuteReportDTO; import io.metersphere.plan.request.ui.UiPlanReportRequest; import io.metersphere.plan.service.remote.api.*; -import io.metersphere.plan.service.remote.performance.PlanLoadTestReportService; import io.metersphere.plan.service.remote.performance.PlanTestPlanLoadCaseService; import io.metersphere.plan.service.remote.ui.PlanTestPlanUiScenarioCaseService; import io.metersphere.plan.utils.TestPlanReportUtil; @@ -70,8 +69,6 @@ public class TestPlanReportService { @Resource PlanTestPlanLoadCaseService planTestPlanLoadCaseService; @Resource - PlanLoadTestReportService planLoadTestReportService; - @Resource ExtTestPlanReportMapper extTestPlanReportMapper; @Resource TestPlanMapper testPlanMapper; @@ -155,7 +152,7 @@ public class TestPlanReportService { TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(testPlanReportDTO.getId()); TestPlanReportContentWithBLOBs content = this.selectTestPlanReportContentByReportId(testPlanReportDTO.getId()); TestPlanReportDataStruct testPlanReportCountData - = testPlanService.buildTestPlanReportStructByTestPlanReport(testPlanReport, content); + = testPlanService.buildOldVersionTestPlanReport(testPlanReport, content); if (testPlanReportCountData != null) { testPlanReportDTO.setPassRate(testPlanReportCountData.getPassRate()); } @@ -546,20 +543,27 @@ public class TestPlanReportService { } //更新测试计划报告的数据结构 - private void updateReportStructInfo(TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs, TestPlanReportDataStruct reportStruct) { + public void updateReportStructInfo(TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs, TestPlanReportDataStruct reportStruct) { //更新BaseCount统计字段和通过率 testPlanReportContentWithBLOBs.setPassRate(reportStruct.getPassRate()); testPlanReportContentWithBLOBs.setApiBaseCount(JSON.toJSONString(reportStruct)); testPlanReportContentMapper.updateByPrimaryKeySelective(testPlanReportContentWithBLOBs); } - public void testPlanExecuteOver(String testPlanReportId, String finishStatus) { - TestPlanReport testPlanReport = this.getTestPlanReport(testPlanReportId); + private boolean isTestPlanCountOver(TestPlanReport testPlanReport) { if (testPlanReport != null && StringUtils.equalsAnyIgnoreCase(testPlanReport.getStatus(), "stopped", TestPlanReportStatus.COMPLETED.name(), TestPlanReportStatus.SUCCESS.name(), TestPlanReportStatus.FAILED.name())) { + return !extTestPlanReportContentMapper.isApiBasicCountIsNull(testPlanReport.getId()); + } + return false; + } + + public void testPlanExecuteOver(String testPlanReportId, String finishStatus) { + TestPlanReport testPlanReport = this.getTestPlanReport(testPlanReportId); + if (this.isTestPlanCountOver(testPlanReport)) { return; } boolean isSendMessage = false; @@ -577,7 +581,7 @@ public class TestPlanReportService { boolean isRerunningTestPlan = BooleanUtils.isTrue(StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), APITestStatus.Rerunning.name())); //测试计划报告结果数据初始化 testPlanReport.setStatus(finishStatus); - content = this.initTestPlanReportInfo(testPlanReport, isRerunningTestPlan); + content = this.countAndSaveTestPlanReport(testPlanReport, isRerunningTestPlan); this.setReportExecuteResult(testPlanReport, finishStatus); } catch (Exception e) { testPlanReport.setStatus(finishStatus); @@ -605,7 +609,7 @@ public class TestPlanReportService { /** * 统计测试计划报告信息 */ - public TestPlanReportContentWithBLOBs initTestPlanReportInfo(TestPlanReport testPlanReport, boolean isRerunningTestPlan) throws Exception { + public TestPlanReportContentWithBLOBs countAndSaveTestPlanReport(TestPlanReport testPlanReport, boolean isRerunningTestPlan) { long endTime = System.currentTimeMillis(); //原逻辑中要判断包含测试计划功能用例时才会赋予结束时间。执行测试计划产生的测试报告,它的结束时间感觉没有这种判断必要。 testPlanReport.setEndTime(endTime); @@ -620,7 +624,7 @@ public class TestPlanReportService { content.setApiBaseCount(null); } TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId()); - TestPlanReportDataStruct apiBaseCountStruct = this.genReportStruct(testPlan, testPlanReport, content, isRerunningTestPlan); + TestPlanReportDataStruct apiBaseCountStruct = testPlanService.generateReportStruct(testPlan, testPlanReport, content, isRerunningTestPlan); if (apiBaseCountStruct.getPassRate() == 1) { testPlanReport.setStatus(TestPlanReportStatus.SUCCESS.name()); } else if (apiBaseCountStruct.getPassRate() < 1) { @@ -674,21 +678,6 @@ public class TestPlanReportService { } } - //构建测试计划报告的数据结构 - private TestPlanReportDataStruct genReportStruct(TestPlanWithBLOBs testPlan, TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs reportContent, boolean rebuildReport) { - TestPlanReportDataStruct returnDTO = null; - if (testPlanReport != null && reportContent != null) { - try { - returnDTO = testPlanService.buildReportStruct(testPlan, testPlanReport, reportContent, rebuildReport); - //查找运行环境 - this.initRunInformation(returnDTO, testPlanReport); - } catch (Exception e) { - LogUtil.error("计算测试计划报告信息出错!", e); - } - } - return returnDTO == null ? new TestPlanReportDataStruct() : returnDTO; - } - /** * @param planReportId 测试计划报告ID * @param resourceRunMode 资源的运行模式,triggerMode非Scedule可以为null @@ -1066,7 +1055,7 @@ public class TestPlanReportService { } if (this.isDynamicallyGenerateReports(testPlanReportContent) || StringUtils.isNotEmpty(testPlanReportContent.getApiBaseCount())) { TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId()); - testPlanReportDTO = this.genReportStruct(testPlan, testPlanReport, testPlanReportContent, false); + testPlanReportDTO = testPlanService.generateReportStruct(testPlan, testPlanReport, testPlanReportContent, false); } testPlanReportDTO.setId(reportId); testPlanReportDTO.setName(testPlanReport.getName()); diff --git a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java index 9c7c065313..fade6ab9ae 100644 --- a/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/test-track/backend/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -1381,9 +1381,11 @@ public class TestPlanService { /** * @param testPlanReport 测试计划报告 * @param testPlanReportContentWithBLOBs 测试计划报告内容 - * @return */ - public TestPlanReportDataStruct buildReportStruct(TestPlanWithBLOBs testPlan, TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs, boolean rebuildReport) { + public TestPlanReportDataStruct generateReportStruct(TestPlanWithBLOBs testPlan, + TestPlanReport testPlanReport, + TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs, + boolean rebuildReport) { TestPlanReportDataStruct testPlanReportStruct = null; if (ObjectUtils.allNotNull(testPlanReport, testPlanReportContentWithBLOBs)) { Map config = null; @@ -1524,7 +1526,10 @@ public class TestPlanService { report.setApiResult(apiResult); report.setUiResult(uiResult); report.setStartTime(testPlanReport.getCreateTime()); - if (testPlanReport.getCreateTime() != testPlanReport.getEndTime() && testPlanReport.getEndTime() != 0) { + if (!StringUtils.equals( + DateUtils.getTimeString(testPlanReport.getCreateTime()), + DateUtils.getTimeString(testPlanReport.getEndTime())) + && testPlanReport.getEndTime() != 0) { //防止测试计划报告非正常状态停止时造成的测试时间显示不对 report.setEndTime(testPlanReport.getEndTime()); } @@ -2108,11 +2113,15 @@ public class TestPlanService { return projectIds.stream().distinct().collect(Collectors.toList()); } - public TestPlanReportDataStruct buildTestPlanReportStructByTestPlanReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContent) { + public TestPlanReportDataStruct buildOldVersionTestPlanReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContent) { TestPlanWithBLOBs testPlanWithBLOBs = this.testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId()); TestPlanReportDataStruct testPlanReportDataStruct = new TestPlanReportDataStruct(); try { - testPlanReportDataStruct = this.buildReportStruct(testPlanWithBLOBs, testPlanReport, testPlanReportContent, false); + testPlanReportDataStruct = this.generateReportStruct(testPlanWithBLOBs, testPlanReport, testPlanReportContent, false); + if (StringUtils.isBlank(testPlanReportContent.getApiBaseCount()) && !testPlanReportDataStruct.hasRunningCase()) { + //旧版本的测试计划报告,没有重新统计过测试计划报告时,且当不存在运行中的用例,会将结果保存下来 + testPlanReportService.updateReportStructInfo(testPlanReportContent, testPlanReportDataStruct); + } } catch (Exception e) { LoggerUtil.error("统计测试计划数据出错!", e); }