diff --git a/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java b/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java index 5510f3839f..3299cfaf24 100644 --- a/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java +++ b/backend/src/main/java/io/metersphere/base/domain/TestPlanReportContentWithBLOBs.java @@ -51,5 +51,7 @@ public class TestPlanReportContentWithBLOBs extends TestPlanReportContent implem private String unExecuteScenarios; + private String apiBaseCount; + private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml index 3afd8df1b1..e2fb768ff0 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/TestPlanReportContentMapper.xml @@ -33,6 +33,7 @@ + @@ -101,7 +102,7 @@ issue_list, api_all_cases, api_failure_cases, scenario_all_cases, scenario_failure_cases, load_all_Cases, load_failure_cases, plan_scenario_report_struct, plan_api_case_report_struct, plan_load_case_report_struct, error_report_cases, error_report_scenarios, un_execute_cases, - un_execute_scenarios + un_execute_scenarios, api_base_count @@ -454,6 +463,9 @@ un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR}, + + api_base_count = #{record.apiBaseCount,jdbcType=LONGVARCHAR}, + @@ -489,7 +501,8 @@ error_report_cases = #{record.errorReportCases,jdbcType=LONGVARCHAR}, error_report_scenarios = #{record.errorReportScenarios,jdbcType=LONGVARCHAR}, un_execute_cases = #{record.unExecuteCases,jdbcType=LONGVARCHAR}, - un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR} + un_execute_scenarios = #{record.unExecuteScenarios,jdbcType=LONGVARCHAR}, + api_base_count = #{record.apiBaseCount,jdbcType=LONGVARCHAR} @@ -595,6 +608,9 @@ un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR}, + + api_base_count = #{apiBaseCount,jdbcType=LONGVARCHAR}, + where id = #{id,jdbcType=VARCHAR} @@ -627,7 +643,8 @@ error_report_cases = #{errorReportCases,jdbcType=LONGVARCHAR}, error_report_scenarios = #{errorReportScenarios,jdbcType=LONGVARCHAR}, un_execute_cases = #{unExecuteCases,jdbcType=LONGVARCHAR}, - un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR} + un_execute_scenarios = #{unExecuteScenarios,jdbcType=LONGVARCHAR}, + api_base_count = #{apiBaseCount,jdbcType=LONGVARCHAR} where id = #{id,jdbcType=VARCHAR} diff --git a/backend/src/main/java/io/metersphere/track/dto/TestPlanReportBuildResultDTO.java b/backend/src/main/java/io/metersphere/track/dto/TestPlanReportBuildResultDTO.java new file mode 100644 index 0000000000..01f50ccb7f --- /dev/null +++ b/backend/src/main/java/io/metersphere/track/dto/TestPlanReportBuildResultDTO.java @@ -0,0 +1,15 @@ +package io.metersphere.track.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TestPlanReportBuildResultDTO { + private TestPlanSimpleReportDTO testPlanSimpleReportDTO; + /** + * 判断testPlanReportContent中,APIBaseInfo字段是否改变。 + * 如果改变过,则需要更新testPlanReportContent数据 + */ + private boolean apiBaseInfoChanged = false; +} diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java index dc38ce984e..af163f3bcf 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanReportService.java @@ -415,16 +415,33 @@ public class TestPlanReportService { } public TestPlanReportContentWithBLOBs updateReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs reportContent) { - if (testPlanReport == null) { + if (testPlanReport == null || reportContent == null) { return null; } TestPlanService testPlanService = CommonBeanFactory.getBean(TestPlanService.class); - TestPlanSimpleReportDTO reportDTO = testPlanService.buildPlanReport(testPlanReport, reportContent); + TestPlanReportBuildResultDTO reportBuildResult = testPlanService.buildPlanReport(testPlanReport, reportContent); + TestPlanSimpleReportDTO reportDTO = reportBuildResult.getTestPlanSimpleReportDTO(); reportDTO.setStartTime(testPlanReport.getStartTime()); reportContent = parseReportDaoToReportContent(testPlanReport.getStatus(), reportDTO, reportContent); + this.updatePassRateAndApiBaseInfoFromReportContent(testPlanReport.getStatus(), reportDTO, reportContent, reportBuildResult.isApiBaseInfoChanged()); return reportContent; } + private void updatePassRateAndApiBaseInfoFromReportContent(String status, TestPlanSimpleReportDTO reportDTO, TestPlanReportContentWithBLOBs reportContent, boolean apiBaseInfoChanged) { + // 如果报告已结束,则更新测试计划报告通过率字段 passRate + if (!StringUtils.equalsIgnoreCase(status, "running") && (Double.compare(reportContent.getPassRate(), reportDTO.getPassRate()) != 0 || apiBaseInfoChanged)) { + TestPlanReportContentExample contentExample = new TestPlanReportContentExample(); + contentExample.createCriteria().andTestPlanReportIdEqualTo(reportContent.getTestPlanReportId()); + TestPlanReportContentWithBLOBs content = new TestPlanReportContentWithBLOBs(); + content.setPassRate(reportDTO.getPassRate()); + if (apiBaseInfoChanged) { + content.setApiBaseCount(reportContent.getApiBaseCount()); + } + testPlanReportContentMapper.updateByExampleSelective(content, contentExample); + } + + } + public TestPlanReport finishedTestPlanReport(String testPlanReportId, String status) { TestPlanReport testPlanReport = this.getTestPlanReport(testPlanReportId); if (testPlanReport != null && StringUtils.equalsIgnoreCase(testPlanReport.getStatus(), "stopped")) { @@ -457,12 +474,7 @@ public class TestPlanReportService { if (CollectionUtils.isNotEmpty(contents)) { content = contents.get(0); } - if (content != null) { - //更新content表对结束日期 - content.setStartTime(testPlanReport.getStartTime()); - content.setEndTime(endTime); - testPlanReportContentMapper.updateByExampleSelective(content, contentExample); - } + //计算测试计划状态 if (StringUtils.equalsIgnoreCase(status, TestPlanReportStatus.COMPLETED.name())) { testPlanReport.setStatus(TestPlanReportStatus.SUCCESS.name()); @@ -474,6 +486,14 @@ public class TestPlanReportService { testPlanReport.setIsScenarioExecuting(false); testPlanReport.setIsPerformanceExecuting(false); + if (content != null) { + //更新content表对结束日期,并计算报表信息 + content.setStartTime(testPlanReport.getStartTime()); + content.setEndTime(endTime); + this.initTestPlanReportBaseCount(testPlanReport,content); + testPlanReportContentMapper.updateByExampleSelective(content, contentExample); + } + TestPlanExecutionQueueExample testPlanExecutionQueueExample = new TestPlanExecutionQueueExample(); testPlanExecutionQueueExample.createCriteria().andReportIdEqualTo(testPlanReportId); List planExecutionQueues = testPlanExecutionQueueMapper.selectByExample(testPlanExecutionQueueExample); @@ -507,6 +527,13 @@ public class TestPlanReportService { return testPlanReport; } + private void initTestPlanReportBaseCount(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs reportContent) { + if(testPlanReport != null && reportContent != null){ + TestPlanReportBuildResultDTO reportBuildResultDTO = testPlanService.buildPlanReport(testPlanReport, reportContent); + reportContent.setApiBaseCount(JSONObject.toJSONString(reportBuildResultDTO.getTestPlanSimpleReportDTO())); + } + } + /** * @param planReportId 测试计划报告ID * @param resourceRunMode 资源的运行模式,triggerMode非Scedule可以为null @@ -621,14 +648,6 @@ public class TestPlanReportService { testPlanReportContentWithBLOBs.setUnExecuteScenarios(JSONObject.toJSONString(reportDTO.getUnExecuteScenarios())); } - // 如果报告已结束,则更新测试计划报告通过率字段 passRate - if (!StringUtils.equalsIgnoreCase(testPlanReportStatus, "running")) { - TestPlanReportContentExample contentExample = new TestPlanReportContentExample(); - contentExample.createCriteria().andTestPlanReportIdEqualTo(testPlanReportId); - TestPlanReportContentWithBLOBs content = new TestPlanReportContentWithBLOBs(); - content.setPassRate(reportDTO.getPassRate()); - testPlanReportContentMapper.updateByExampleSelective(content, contentExample); - } return testPlanReportContentWithBLOBs; } diff --git a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java index e27f1282b4..b6b39bd1ca 100644 --- a/backend/src/main/java/io/metersphere/track/service/TestPlanService.java +++ b/backend/src/main/java/io/metersphere/track/service/TestPlanService.java @@ -1735,6 +1735,7 @@ public class TestPlanService { public void buildLoadReport(TestPlanSimpleReportDTO report, JSONObject config, Map loadCaseReportMap, boolean saveResponse) { if (MapUtils.isEmpty(loadCaseReportMap)) { + report.setLoadAllCases(new ArrayList<>()); return; } if (checkReportConfig(config, "load")) { @@ -1759,7 +1760,13 @@ public class TestPlanService { } } - public TestPlanSimpleReportDTO buildPlanReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) { + /** + * @param testPlanReport 测试计划报告 + * @param testPlanReportContentWithBLOBs 测试计划报告内容 + * @return + */ + public TestPlanReportBuildResultDTO buildPlanReport(TestPlanReport testPlanReport, TestPlanReportContentWithBLOBs testPlanReportContentWithBLOBs) { + TestPlanReportBuildResultDTO returnDTO = new TestPlanReportBuildResultDTO(); TestPlanWithBLOBs testPlan = testPlanMapper.selectByPrimaryKey(testPlanReport.getTestPlanId()); if (testPlan != null) { String reportConfig = testPlan.getReportConfig(); @@ -1768,13 +1775,44 @@ public class TestPlanService { config = JSONObject.parseObject(reportConfig); } TestPlanExecuteReportDTO testPlanExecuteReportDTO = testPlanReportService.genTestPlanExecuteReportDTOByTestPlanReportContent(testPlanReportContentWithBLOBs); - TestPlanSimpleReportDTO report = getReport(testPlanReport.getTestPlanId(), testPlanExecuteReportDTO); - buildFunctionalReport(report, config, testPlanReport.getTestPlanId()); - buildApiReport(report, config, testPlanExecuteReportDTO); - buildLoadReport(report, config, testPlanExecuteReportDTO.getTestPlanLoadCaseIdAndReportIdMap(), false); - return report; + TestPlanSimpleReportDTO report = null; + boolean apiBaseInfoChanged = false; + if (StringUtils.isEmpty(testPlanReportContentWithBLOBs.getApiBaseCount())) { + report = getReport(testPlanReport.getTestPlanId(), testPlanExecuteReportDTO); + apiBaseInfoChanged = true; + } else { + try { + report = JSONObject.parseObject(testPlanReportContentWithBLOBs.getApiBaseCount(), TestPlanSimpleReportDTO.class); + } catch (Exception e) { + LogUtil.info("解析接口统计数据出错!数据:" + testPlanReportContentWithBLOBs.getApiBaseCount(), e); + } + if (report == null) { + report = getReport(testPlanReport.getTestPlanId(), testPlanExecuteReportDTO); + apiBaseInfoChanged = true; + } + } + if(report.getFunctionAllCases() == null || report.getIssueList() == null){ + buildFunctionalReport(report, config, testPlanReport.getTestPlanId()); + apiBaseInfoChanged = true; + } + if(report.getApiAllCases() == null && report.getScenarioAllCases() == null){ + buildApiReport(report, config, testPlanExecuteReportDTO); + apiBaseInfoChanged = true; + } + if(report.getLoadAllCases() == null){ + buildLoadReport(report, config, testPlanExecuteReportDTO.getTestPlanLoadCaseIdAndReportIdMap(), false); + apiBaseInfoChanged = true; + } + returnDTO.setTestPlanSimpleReportDTO(report); + + if(apiBaseInfoChanged){ + testPlanReportContentWithBLOBs.setApiBaseCount(JSONObject.toJSONString(report)); + returnDTO.setApiBaseInfoChanged(true); + } + return returnDTO; } else { - return null; + returnDTO.setTestPlanSimpleReportDTO(new TestPlanSimpleReportDTO()); + return returnDTO; } } diff --git a/backend/src/main/resources/db/migration/V125__1.20.16__release.sql b/backend/src/main/resources/db/migration/V125__1.20.16__release.sql index c5bd6f3743..f041ef959a 100644 --- a/backend/src/main/resources/db/migration/V125__1.20.16__release.sql +++ b/backend/src/main/resources/db/migration/V125__1.20.16__release.sql @@ -2,4 +2,7 @@ ALTER TABLE load_test_report MODIFY name VARCHAR(255) NOT NULL; ALTER TABLE load_test_report - MODIFY test_name VARCHAR(255) NULL; \ No newline at end of file + MODIFY test_name VARCHAR(255) NULL; + +ALTER TABLE `test_plan_report_content` + ADD COLUMN `api_base_count` LONGTEXT COMMENT 'request (JSON format)'; \ No newline at end of file