From c61d57129656002f18710f76c195d8cd377c8e16 Mon Sep 17 00:00:00 2001 From: Jianguo-Genius Date: Mon, 2 Dec 2024 16:59:25 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E5=A2=9E=E5=8A=A0=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E5=92=8C=E6=9C=AA=E9=80=9A=E8=BF=87=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=9D=A1=E4=BB=B6=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sdk/constants/TestPlanConstants.java | 5 + .../io/metersphere/sdk/util/SubListUtils.java | 25 + .../plan/dto/TestPlanCalculationDTO.java | 167 +++++++ .../dto/request/TestPlanTableRequest.java | 4 + .../plan/mapper/ExtTestPlanApiCaseMapper.java | 2 + .../plan/mapper/ExtTestPlanApiCaseMapper.xml | 14 + .../mapper/ExtTestPlanApiScenarioMapper.java | 2 + .../mapper/ExtTestPlanApiScenarioMapper.xml | 14 + .../ExtTestPlanFunctionalCaseMapper.java | 2 + .../ExtTestPlanFunctionalCaseMapper.xml | 14 + .../plan/mapper/ExtTestPlanMapper.java | 5 + .../plan/mapper/ExtTestPlanMapper.xml | 14 + .../plan/service/TestPlanApiCaseService.java | 5 + .../service/TestPlanApiScenarioService.java | 5 + .../service/TestPlanBaseUtilsService.java | 14 +- .../plan/service/TestPlanBugService.java | 5 + .../TestPlanFunctionalCaseService.java | 5 + .../service/TestPlanManagementService.java | 295 +++++++++--- .../plan/service/TestPlanResourceService.java | 2 + .../plan/service/TestPlanService.java | 2 +- .../metersphere/plan/utils/TestPlanUtils.java | 30 ++ ...ests.java => TestPlanControllerTests.java} | 434 +++++++++++++----- 22 files changed, 884 insertions(+), 181 deletions(-) create mode 100644 backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCalculationDTO.java create mode 100644 backend/services/test-plan/src/main/java/io/metersphere/plan/utils/TestPlanUtils.java rename backend/services/test-plan/src/test/java/io/metersphere/plan/controller/{TestPlanTests.java => TestPlanControllerTests.java} (86%) diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/TestPlanConstants.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/TestPlanConstants.java index b3641104a1..b99a82a0c7 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/TestPlanConstants.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/TestPlanConstants.java @@ -22,4 +22,9 @@ public class TestPlanConstants { public static final String TEST_PLAN_SHOW_STATUS_UNDERWAY = "UNDERWAY"; //测试计划对外展示状态-已完成 public static final String TEST_PLAN_SHOW_STATUS_COMPLETED = "COMPLETED"; + + //测试计划对外展示状态-通过 + public static final String TEST_PLAN_SHOW_STATUS_PASSED = "PASSED"; + //测试计划对外展示状态-未通过 + public static final String TEST_PLAN_SHOW_STATUS_NOT_PASSED = "NOT_PASSED"; } diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/SubListUtils.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/SubListUtils.java index 4073430a63..5803a6a7fc 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/SubListUtils.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/util/SubListUtils.java @@ -1,9 +1,12 @@ package io.metersphere.sdk.util; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.function.Consumer; public class SubListUtils { @@ -28,4 +31,26 @@ public class SubListUtils { } } + + public static void dealForSubMap(Map totalMap, int batchSize, Consumer> subFunc) { + if (MapUtils.isEmpty(totalMap)) { + return; + } + + Map dealMap = new LinkedHashMap<>(totalMap); + while (dealMap.size() > batchSize) { + Map subMap = new LinkedHashMap<>(); + dealMap.forEach((k, v) -> { + if (subMap.size() < batchSize) { + subMap.put(k, v); + } + }); + subFunc.accept(subMap); + subMap.forEach(dealMap::remove); + } + if (MapUtils.isNotEmpty(dealMap)) { + subFunc.accept(dealMap); + } + } + } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCalculationDTO.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCalculationDTO.java new file mode 100644 index 0000000000..374ff7401e --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/TestPlanCalculationDTO.java @@ -0,0 +1,167 @@ +package io.metersphere.plan.dto; + +import io.metersphere.sdk.constants.TestPlanConstants; +import lombok.Data; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class TestPlanCalculationDTO { + + private List statusConditionList; + private List passedConditionList; + + private List passedTestPlanIds = new ArrayList<>(); + private List passedItemTestPlanIds = new ArrayList<>(); + private List notPassedTestPlanIds = new ArrayList<>(); + private List notPassedItemTestPlanIds = new ArrayList<>(); + + private List completedTestPlanIds = new ArrayList<>(); + private List completedItemTestPlanIds = new ArrayList<>(); + private List preparedTestPlanIds = new ArrayList<>(); + private List preparedItemTestPlanIds = new ArrayList<>(); + private List underwayTestPlanIds = new ArrayList<>(); + private List underwayItemTestPlanIds = new ArrayList<>(); + + public void addPassedTestPlanId(String testPlanId) { + if (!passedTestPlanIds.contains(testPlanId)) { + passedTestPlanIds.add(testPlanId); + } + } + + public void addPassedItemTestPlanId(String testPlanId) { + if (!passedItemTestPlanIds.contains(testPlanId)) { + passedItemTestPlanIds.add(testPlanId); + } + } + + public void addNotPassedTestPlanId(String testPlanId) { + if (!notPassedTestPlanIds.contains(testPlanId)) { + notPassedTestPlanIds.add(testPlanId); + } + } + + public void addNotPassedItemTestPlanId(String testPlanId) { + if (!notPassedItemTestPlanIds.contains(testPlanId)) { + notPassedItemTestPlanIds.add(testPlanId); + } + } + + public void addCompletedTestPlanId(String testPlanId) { + if (!completedTestPlanIds.contains(testPlanId)) { + completedTestPlanIds.add(testPlanId); + } + } + + public void addCompletedItemTestPlanId(String testPlanId) { + if (!completedItemTestPlanIds.contains(testPlanId)) { + completedItemTestPlanIds.add(testPlanId); + } + } + + public void addPreparedTestPlanId(String testPlanId) { + if (!preparedTestPlanIds.contains(testPlanId)) { + preparedTestPlanIds.add(testPlanId); + } + } + + public void addPreparedItemTestPlanId(String testPlanId) { + if (!preparedItemTestPlanIds.contains(testPlanId)) { + preparedItemTestPlanIds.add(testPlanId); + } + } + + + public void addUnderwayTestPlanId(String testPlanId) { + if (!underwayTestPlanIds.contains(testPlanId)) { + underwayTestPlanIds.add(testPlanId); + } + } + + public void addUnderwayItemTestPlanId(String testPlanId) { + if (!underwayItemTestPlanIds.contains(testPlanId)) { + underwayItemTestPlanIds.add(testPlanId); + } + } + + public void merge(TestPlanCalculationDTO dto) { + passedTestPlanIds.addAll(dto.getPassedTestPlanIds()); + notPassedTestPlanIds.addAll(dto.getNotPassedTestPlanIds()); + completedTestPlanIds.addAll(dto.getCompletedTestPlanIds()); + preparedTestPlanIds.addAll(dto.getPreparedTestPlanIds()); + underwayTestPlanIds.addAll(dto.getUnderwayTestPlanIds()); + + passedItemTestPlanIds.addAll(dto.getPassedItemTestPlanIds()); + notPassedItemTestPlanIds.addAll(dto.getNotPassedItemTestPlanIds()); + completedItemTestPlanIds.addAll(dto.getCompletedItemTestPlanIds()); + preparedItemTestPlanIds.addAll(dto.getPreparedItemTestPlanIds()); + underwayItemTestPlanIds.addAll(dto.getUnderwayItemTestPlanIds()); + } + + public List getConditionInnerId() { + List passedConditionInnerId = new ArrayList<>(); + List statusConditionInnerId = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(passedConditionList)) { + passedConditionList.forEach(condition -> { + if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)) { + passedConditionInnerId.addAll(this.passedTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED)) { + passedConditionInnerId.addAll(this.notPassedTestPlanIds); + } + }); + } + if (CollectionUtils.isNotEmpty(statusConditionList)) { + statusConditionList.forEach(status -> { + if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + statusConditionInnerId.addAll(this.completedTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + statusConditionInnerId.addAll(this.preparedTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + statusConditionInnerId.addAll(this.underwayTestPlanIds); + } + }); + } + + if (CollectionUtils.isNotEmpty(statusConditionInnerId) && CollectionUtils.isNotEmpty(passedConditionInnerId)) { + return statusConditionInnerId.stream().filter(passedConditionInnerId::contains).toList(); + } else { + return ListUtils.union(statusConditionInnerId, passedConditionInnerId); + } + } + + + public List getConditionItemPlanId() { + List passedConditionInnerId = new ArrayList<>(); + List statusConditionInnerId = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(passedConditionList)) { + passedConditionList.forEach(condition -> { + if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)) { + passedConditionInnerId.addAll(this.passedItemTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(condition, TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED)) { + passedConditionInnerId.addAll(this.notPassedItemTestPlanIds); + } + }); + } + if (CollectionUtils.isNotEmpty(statusConditionList)) { + statusConditionList.forEach(status -> { + if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + statusConditionInnerId.addAll(this.completedItemTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + statusConditionInnerId.addAll(this.preparedItemTestPlanIds); + } else if (StringUtils.equalsIgnoreCase(status, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + statusConditionInnerId.addAll(this.underwayItemTestPlanIds); + } + }); + } + + if (CollectionUtils.isNotEmpty(statusConditionInnerId) && CollectionUtils.isNotEmpty(passedConditionInnerId)) { + return statusConditionInnerId.stream().filter(passedConditionInnerId::contains).toList(); + } else { + return ListUtils.union(statusConditionInnerId, passedConditionInnerId); + } + } +} diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTableRequest.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTableRequest.java index e35472a3cd..d359ff7832 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTableRequest.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/dto/request/TestPlanTableRequest.java @@ -43,6 +43,10 @@ public class TestPlanTableRequest extends BasePageRequest { @Schema(description = "额外的子计划ID集合") private List extraIncludeChildIds; + + @Schema(description = "应当包含的子测试计划ID (用于程序内部筛选过滤)") + private List includeItemTestPlanIds; + public String getSortString() { if (StringUtils.isEmpty(super.getSortString())) { return "t.update_time desc"; diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.java index 34d934d408..16ebe17cb9 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.java @@ -84,4 +84,6 @@ public interface ExtTestPlanApiCaseMapper { Integer countByPlanIds(@Param("planIds") List planIds); List selectLastExecResultByTestPlanIds(@Param("testPlanIds") List testPlanIds); + + List selectLastExecResultByProjectId(String projectId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.xml index 6194cbf221..7712306b32 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiCaseMapper.xml @@ -910,6 +910,7 @@ + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.java index 14ff7dc234..65f5fc634f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.java @@ -81,4 +81,6 @@ public interface ExtTestPlanApiScenarioMapper { Integer countByPlanIds(@Param("planIds") List planIds); List selectLastExecResultByTestPlanIds(@Param("testPlanIds") List testPlanIds); + + List selectLastExecResultByProjectId(String projectId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.xml index f921a8de18..00171b1497 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanApiScenarioMapper.xml @@ -680,6 +680,7 @@ + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java index d9775c10f7..0dfc64915b 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.java @@ -89,4 +89,6 @@ public interface ExtTestPlanFunctionalCaseMapper { Collection selectIdsByRootIds(@Param("rootIds") List rootIds, @Param("testPlanId") String testPlanId); List selectLastExecResultByTestPlanIds(@Param("testPlanIds") List testPlanIds); + + List selectLastExecResultByProjectId(String projectId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml index 3759b7c4ca..f0bdd76f6d 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanFunctionalCaseMapper.xml @@ -807,6 +807,7 @@ + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java index 78d1def96c..e95773964c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.java @@ -1,6 +1,7 @@ package io.metersphere.plan.mapper; import io.metersphere.plan.domain.TestPlan; +import io.metersphere.plan.domain.TestPlanConfig; import io.metersphere.plan.dto.TestPlanAndGroupInfoDTO; import io.metersphere.plan.dto.TestPlanExecuteHisDTO; import io.metersphere.plan.dto.TestPlanGroupCountDTO; @@ -107,4 +108,8 @@ public interface ExtTestPlanMapper { TestPlan getLatestPlan(@Param("projectId") String projectId); + + List selectTestPlanConfigByTestPlanIds(@Param("testPlanIds") List testPlanIds); + + List selectIdAndGroupIdByProjectId(String projectId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml index 2c010691ae..7bab087f9e 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanMapper.xml @@ -952,6 +952,20 @@ where type = 'TEST_PLAN' and status='NOT_ARCHIVED' and project_id = #{projectId} order by create_time desc limit 1; + + diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java index 5f592f2fb4..8b968fe1f7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiCaseService.java @@ -151,6 +151,11 @@ public class TestPlanApiCaseService extends TestPlanResourceService { return extTestPlanApiCaseMapper.selectLastExecResultByTestPlanIds(testPlanIds); } + @Override + public List selectLastExecResultByProjectId(String projectId) { + return extTestPlanApiCaseMapper.selectLastExecResultByProjectId(projectId); + } + @Override public void deleteBatchByTestPlanId(List testPlanIdList) { TestPlanApiCaseExample example = new TestPlanApiCaseExample(); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java index 99606b96ab..956dcda8ec 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanApiScenarioService.java @@ -139,6 +139,11 @@ public class TestPlanApiScenarioService extends TestPlanResourceService { return extTestPlanApiScenarioMapper.selectLastExecResultByTestPlanIds(testPlanIds); } + @Override + public List selectLastExecResultByProjectId(String projectId) { + return extTestPlanApiScenarioMapper.selectLastExecResultByProjectId(projectId); + } + @Override public void deleteBatchByTestPlanId(List testPlanIdList) { TestPlanApiScenarioExample example = new TestPlanApiScenarioExample(); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBaseUtilsService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBaseUtilsService.java index 7e16644974..f8b2d81ee7 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBaseUtilsService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBaseUtilsService.java @@ -4,12 +4,14 @@ import io.metersphere.plan.dto.TestPlanResourceExecResultDTO; import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.sdk.constants.ModuleConstants; +import io.metersphere.sdk.constants.ResultStatus; import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.util.Translator; import io.metersphere.system.domain.TestPlanModuleExample; import io.metersphere.system.mapper.TestPlanModuleMapper; import jakarta.annotation.Resource; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -76,13 +78,23 @@ public class TestPlanBaseUtilsService { } public String calculateTestPlanStatus(List resultList) { - List calculateList = resultList.stream().distinct().toList(); //目前只有三个状态。如果同时包含多种状态(进行中/未开始、进行中/已完成、已完成/未开始、进行中/未开始/已完成),根据算法可得测试计划都会是进行中 + List allStatus = new ArrayList<>(); + resultList.stream().distinct().forEach(item -> { + if (StringUtils.equalsAnyIgnoreCase(item, ResultStatus.BLOCKED.name(), ResultStatus.FAKE_ERROR.name(), ResultStatus.ERROR.name(), ResultStatus.SUCCESS.name(), TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + allStatus.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + } else { + allStatus.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + } + }); + List calculateList = allStatus.stream().distinct().toList(); if (calculateList.size() == 1) { if (calculateList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { return TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED; } else return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED; + } else if (CollectionUtils.isEmpty(calculateList)) { + return TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED; } else { return TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY; } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBugService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBugService.java index cca9e22278..8171ab290c 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBugService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanBugService.java @@ -68,6 +68,11 @@ public class TestPlanBugService extends TestPlanResourceService { return List.of(); } + @Override + public List selectLastExecResultByProjectId(String projectId) { + return List.of(); + } + @Override public List selectDistinctExecResultByTestPlanIds(List testPlanIds) { return List.of(); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java index 02639fd88f..c6e487cb5b 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanFunctionalCaseService.java @@ -138,6 +138,11 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService { return extTestPlanFunctionalCaseMapper.selectDistinctExecResult(projectId); } + @Override + public List selectLastExecResultByProjectId(String projectId) { + return extTestPlanFunctionalCaseMapper.selectLastExecResultByProjectId(projectId); + } + @Override public List selectDistinctExecResultByTestPlanIds(List testPlanIds) { return extTestPlanFunctionalCaseMapper.selectDistinctExecResultByTestPlanIds(testPlanIds); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java index ea6e9e7516..bd4b752a0e 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanManagementService.java @@ -4,8 +4,9 @@ import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.plan.constants.TestPlanResourceConfig; import io.metersphere.plan.domain.TestPlan; +import io.metersphere.plan.domain.TestPlanConfig; import io.metersphere.plan.domain.TestPlanExample; -import io.metersphere.plan.dto.TestPlanGroupCountDTO; +import io.metersphere.plan.dto.TestPlanCalculationDTO; import io.metersphere.plan.dto.TestPlanResourceExecResultDTO; import io.metersphere.plan.dto.request.TestPlanTableRequest; import io.metersphere.plan.dto.response.TestPlanResponse; @@ -14,12 +15,16 @@ import io.metersphere.plan.mapper.ExtTestPlanFunctionalCaseMapper; import io.metersphere.plan.mapper.ExtTestPlanMapper; import io.metersphere.plan.mapper.ExtTestPlanModuleMapper; import io.metersphere.plan.mapper.TestPlanMapper; +import io.metersphere.plan.utils.TestPlanUtils; import io.metersphere.project.domain.Project; import io.metersphere.project.dto.ModuleCountDTO; import io.metersphere.project.mapper.ProjectMapper; +import io.metersphere.sdk.constants.ResultStatus; import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.exception.MSException; +import io.metersphere.sdk.util.CalculateUtils; import io.metersphere.sdk.util.JSON; +import io.metersphere.sdk.util.SubListUtils; import io.metersphere.sdk.util.Translator; import io.metersphere.system.utils.PageUtils; import io.metersphere.system.utils.Pager; @@ -81,7 +86,7 @@ public class TestPlanManagementService { this.initDefaultFilter(request); Page page = PageHelper.startPage(request.getCurrent(), request.getPageSize(), MapUtils.isEmpty(request.getSort()) ? "t.pos desc, t.id desc" : request.getSortString("id", "t")); - return PageUtils.setPageInfo(page, this.list(request)); + return PageUtils.setPageInfo(page, this.list(request, request.getIncludeItemTestPlanIds())); } public void filterTestPlanIdWithStatus(Map> testPlanExecMap, List completedTestPlanIds, List preparedTestPlanIds, List underwayTestPlanIds) { @@ -131,61 +136,194 @@ public class TestPlanManagementService { return returnIdList; } - private List selectTestPlanIdByProjectIdAndStatus(String projectId, @NotEmpty List statusList) { - List innerIdList = new ArrayList<>(); - Map beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class); - // 将当前项目下未归档的测试计划结果查询出来,进行下列符合条件的筛选 - List execResults = new ArrayList<>(); - beansOfType.forEach((k, v) -> execResults.addAll(v.selectDistinctExecResultByProjectId(projectId))); - Map>> testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults); - Map groupCountMap = extTestPlanMapper.countByGroupPlan(projectId) - .stream().collect(Collectors.toMap(TestPlanGroupCountDTO::getGroupId, TestPlanGroupCountDTO::getCount)); - - List completedTestPlanIds = new ArrayList<>(); - List preparedTestPlanIds = new ArrayList<>(); - List underwayTestPlanIds = new ArrayList<>(); - testPlanExecMap.forEach((groupId, planMap) -> { - if (StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) { - this.filterTestPlanIdWithStatus(planMap, completedTestPlanIds, preparedTestPlanIds, underwayTestPlanIds); - } else { - long itemPlanCount = groupCountMap.getOrDefault(groupId, 0L); - List itemStatusList = new ArrayList<>(); - if (itemPlanCount > planMap.size()) { - // 存在未执行或者没有用例的测试计划。 此时这种测试计划的状态为未开始 - itemStatusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); - } - planMap.forEach((planId, resultList) -> { - itemStatusList.add(testPlanBaseUtilsService.calculateTestPlanStatus(resultList)); - }); - String groupStatus = testPlanBaseUtilsService.calculateStatusByChildren(itemStatusList); - if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { - completedTestPlanIds.add(groupId); - } else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { - underwayTestPlanIds.add(groupId); - } else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { - preparedTestPlanIds.add(groupId); + /** + * 根据项目ID和状态查询包含的测试计划ID + * + * @param projectId 项目ID + * @param dataType 页面视图 ( 全部(查找符合条件的测试计划或测试子计划) 计划(查找符合条件的测试子计划) 计划组(查找符合条件的测试计划组)) + * @param statusConditionList 状态列表 + * @return 测试计划ID列表 + */ + public TestPlanCalculationDTO selectTestPlanIdByProjectIdUnionConditions(String projectId, String dataType, List statusConditionList, List passedConditionList) { + if (CollectionUtils.isEmpty(statusConditionList) && CollectionUtils.isEmpty(passedConditionList)) { + return new TestPlanCalculationDTO(); + } + boolean selectPassed = CollectionUtils.isNotEmpty(passedConditionList) && CollectionUtils.size(passedConditionList) == 1; + List testPlanList = extTestPlanMapper.selectIdAndGroupIdByProjectId(projectId); + Map> testPlanGroupIdMap = new HashMap<>(); + List noGroupPlanIdList = new ArrayList<>(); + Map> noGroupPlanIdMap = new HashMap<>(); + if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN)) { + //只查游离态的测试计划 + for (TestPlan item : testPlanList) { + if (StringUtils.equalsIgnoreCase(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && StringUtils.equals(item.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) { + noGroupPlanIdList.add(item.getId()); } } + } else if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_GROUP)) { + //不查游离态的测试计划 + testPlanList = testPlanList.stream().filter(item -> + StringUtils.equalsIgnoreCase(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) || !StringUtils.equals(item.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID) + ).toList(); + testPlanGroupIdMap = TestPlanUtils.parseGroupIdMap(testPlanList); + } else { + // 全部查询 + testPlanGroupIdMap = TestPlanUtils.parseGroupIdMap(testPlanList); + noGroupPlanIdList = testPlanGroupIdMap.get(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID); + testPlanGroupIdMap.remove(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID); + } + noGroupPlanIdMap.put(TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID, noGroupPlanIdList); + testPlanList = null; + + Map beansOfType = applicationContext.getBeansOfType(TestPlanResourceService.class); + + TestPlanCalculationDTO calculationDTO = this.calculationTestPlanByConditions(noGroupPlanIdMap, beansOfType, selectPassed, dataType); + + SubListUtils.dealForSubMap(testPlanGroupIdMap, 50, groupIdMap -> { + TestPlanCalculationDTO dto = this.calculationTestPlanByConditions(groupIdMap, beansOfType, selectPassed, dataType); + calculationDTO.merge(dto); }); - testPlanExecMap = null; - if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { - // 已完成 - innerIdList.addAll(completedTestPlanIds); + calculationDTO.setStatusConditionList(statusConditionList); + calculationDTO.setPassedConditionList(passedConditionList); + + return calculationDTO; + } + + private TestPlanCalculationDTO calculationTestPlanByConditions(Map> groupIdMap, Map beansOfType, boolean selectPassed, String dataType) { + TestPlanCalculationDTO returnDTO = new TestPlanCalculationDTO(); + List selectTestPlanIds = new ArrayList<>(); + groupIdMap.forEach((k, v) -> selectTestPlanIds.addAll(v)); + if (CollectionUtils.isEmpty(selectTestPlanIds)) { + return returnDTO; + } + // 将当前项目下未归档的测试计划结果查询出来,进行下列符合条件的筛选 + List execResults = new ArrayList<>(); + Map>> testPlanExecMap = null; + + if (selectPassed) { + beansOfType.forEach((k, v) -> execResults.addAll(v.selectLastExecResultByTestPlanIds(selectTestPlanIds))); + testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults); + Map testPlanConfigMap = extTestPlanMapper.selectTestPlanConfigByTestPlanIds(selectTestPlanIds) + .stream().collect(Collectors.toMap(TestPlanConfig::getTestPlanId, item -> item)); + for (Map.Entry> entry : groupIdMap.entrySet()) { + String groupId = entry.getKey(); + List testPlanIdList = entry.getValue(); + Map> testPlanExecResult = testPlanExecMap.containsKey(groupId) ? testPlanExecMap.get(groupId) : new HashMap<>(); + boolean isRootTestPlan = StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID); + boolean groupHasUnPassItem = false; + + for (String testPlanId : testPlanIdList) { + TestPlanConfig config = testPlanConfigMap.get(testPlanId); + double passThreshold = (config == null || config.getPassThreshold() == null) ? 100 : config.getPassThreshold(); + + List executeResultList = testPlanExecResult.containsKey(testPlanId) ? testPlanExecResult.get(testPlanId) : new ArrayList<>(); + + double executeRage = CalculateUtils.percentage( + executeResultList.stream().filter(result -> StringUtils.equalsIgnoreCase(result, ResultStatus.SUCCESS.name())).toList().size(), + executeResultList.size()); + + if (executeRage < passThreshold) { + groupHasUnPassItem = true; + } + + if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && isRootTestPlan) { + if (executeRage >= passThreshold) { + returnDTO.addPassedTestPlanId(testPlanId); + } else { + returnDTO.addNotPassedTestPlanId(testPlanId); + } + } else if (StringUtils.equalsAnyIgnoreCase(dataType, "ALL")) { + if (executeRage >= passThreshold) { + if (isRootTestPlan) { + returnDTO.addPassedTestPlanId(testPlanId); + } else { + returnDTO.addPassedTestPlanId(groupId); + returnDTO.addPassedItemTestPlanId(testPlanId); + } + + } else { + if (isRootTestPlan) { + returnDTO.addNotPassedTestPlanId(testPlanId); + } else { + returnDTO.addNotPassedTestPlanId(groupId); + returnDTO.addNotPassedItemTestPlanId(testPlanId); + } + } + } + } + + if (!StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !isRootTestPlan) { + if (groupHasUnPassItem || CollectionUtils.isEmpty(testPlanIdList)) { + returnDTO.addNotPassedTestPlanId(groupId); + } else { + returnDTO.addPassedTestPlanId(groupId); + } + } + } + } else { + beansOfType.forEach((k, v) -> execResults.addAll(v.selectDistinctExecResultByTestPlanIds(selectTestPlanIds))); + testPlanExecMap = testPlanBaseUtilsService.parseExecResult(execResults); } - if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { - // 进行中 - innerIdList.addAll(underwayTestPlanIds); + for (Map.Entry> entry : groupIdMap.entrySet()) { + String groupId = entry.getKey(); + List testPlanIdList = entry.getValue(); + Map> testPlanExecResult = testPlanExecMap.containsKey(groupId) ? testPlanExecMap.get(groupId) : new HashMap<>(); + boolean isRootTestPlan = StringUtils.equalsIgnoreCase(groupId, TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID); + + List testPlanStatus = new ArrayList<>(); + for (String testPlanId : testPlanIdList) { + List executeResultList = testPlanExecResult.containsKey(testPlanId) ? testPlanExecResult.get(testPlanId) : new ArrayList<>(); + String result = testPlanBaseUtilsService.calculateTestPlanStatus(executeResultList); + testPlanStatus.add(result); + if (StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && isRootTestPlan) { + if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + returnDTO.addCompletedTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + returnDTO.addUnderwayTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + returnDTO.addPreparedTestPlanId(testPlanId); + } + } else if (StringUtils.equalsAnyIgnoreCase(dataType, "ALL")) { + if (isRootTestPlan) { + if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + returnDTO.addCompletedTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + returnDTO.addUnderwayTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + returnDTO.addPreparedTestPlanId(testPlanId); + } + } else { + if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + returnDTO.addCompletedTestPlanId(groupId); + returnDTO.addCompletedItemTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + returnDTO.addUnderwayTestPlanId(groupId); + returnDTO.addUnderwayItemTestPlanId(testPlanId); + } else if (StringUtils.equals(result, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + returnDTO.addPreparedTestPlanId(groupId); + returnDTO.addPreparedItemTestPlanId(testPlanId); + + } + } + } + } + + if (!StringUtils.equalsIgnoreCase(dataType, TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !isRootTestPlan) { + String groupStatus = testPlanBaseUtilsService.calculateStatusByChildren(testPlanStatus); + if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)) { + returnDTO.addCompletedTestPlanId(groupId); + } else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)) { + returnDTO.addUnderwayTestPlanId(groupId); + } else if (StringUtils.equals(groupStatus, TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { + returnDTO.addPreparedTestPlanId(groupId); + } + + } + } - if (statusList.contains(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)) { - // 未开始 有一些测试计划/计划组没有用例 / 测试计划, 在上面的计算中无法过滤。所以用排除法机型处理 - List withoutList = new ArrayList<>(); - withoutList.addAll(completedTestPlanIds); - withoutList.addAll(underwayTestPlanIds); - innerIdList.addAll(extTestPlanMapper.selectIdByProjectIdAndWithoutList(projectId, withoutList)); - } - return innerIdList; + return returnDTO; } @Autowired @@ -202,13 +340,23 @@ public class TestPlanManagementService { item.setValue(defaultStatusList); //目前未归档的测试计划只有3中类型。所以这里判断如果是3个的话等于直接查询未归档 if (statusList.size() < 3) { - request.setCombineInnerIds(this.selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), statusList)); + TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), request.getType(), statusList, null); + request.setCombineInnerIds(calculationDTO.getConditionInnerId()); + request.setIncludeItemTestPlanIds(calculationDTO.getConditionItemPlanId()); request.setCombineOperator(item.getOperator()); + + if (CollectionUtils.isEmpty(request.getCombineInnerIds())) { + // 如果查询条件内未查出包含ID,意味着查不出任何一条数据。 + request.setCombineInnerIds(Collections.singletonList("COMBINE_SEARCH_NONE")); + } } } }); }); if (!StringUtils.equalsIgnoreCase(request.getViewId(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) { + List statusSelectParam = null; + List passedSelectParam = null; + if (request.getFilter() == null || !request.getFilter().containsKey("status")) { if (request.getFilter() == null) { request.setFilter(new HashMap<>() {{ @@ -218,13 +366,31 @@ public class TestPlanManagementService { request.getFilter().put("status", defaultStatusList); } } else if (!request.getFilter().get("status").contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) { - List statusList = request.getFilter().get("status"); + statusSelectParam = request.getFilter().get("status"); request.getFilter().put("status", defaultStatusList); - //目前未归档的测试计划只有3中类型。所以这里判断如果是3个的话等于直接查询未归档 - if (statusList.size() < 3) { - request.setInnerIds(this.selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), statusList)); + } + + if (request.getFilter() != null && request.getFilter().containsKey("passed")) { + passedSelectParam = request.getFilter().get("passed"); + } + + boolean selectArchived = CollectionUtils.isNotEmpty(statusSelectParam) && statusSelectParam.contains(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED); + boolean selectStatus = !selectArchived && CollectionUtils.isNotEmpty(statusSelectParam) && CollectionUtils.size(statusSelectParam) < 3; + boolean selectPassed = CollectionUtils.isNotEmpty(passedSelectParam) && CollectionUtils.size(passedSelectParam) == 1; + + if (selectStatus || selectPassed) { + TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), request.getType(), + selectStatus ? statusSelectParam : null, + selectPassed ? passedSelectParam : null); + request.setInnerIds(calculationDTO.getConditionInnerId()); + request.setIncludeItemTestPlanIds(calculationDTO.getConditionItemPlanId()); + + if (CollectionUtils.isEmpty(request.getInnerIds()) && !selectArchived) { + // 如果查询条件内未查出包含ID,意味着查不出任何一条数据。 + request.setCombineInnerIds(Collections.singletonList("FILTER_SEARCH_NONE")); } } + } if (StringUtils.isNotBlank(request.getKeyword())) { @@ -236,14 +402,15 @@ public class TestPlanManagementService { } } - public List list(TestPlanTableRequest request) { + public List list(TestPlanTableRequest request, List includeChildTestPlanId) { List testPlanResponses = new ArrayList<>(); if (StringUtils.equalsIgnoreCase(request.getViewId(), "my_follow")) { testPlanResponses = extTestPlanMapper.selectMyFollowByConditions(request); } else { testPlanResponses = extTestPlanMapper.selectByConditions(request); } - handChildren(testPlanResponses, request.getProjectId()); + + handChildren(testPlanResponses, includeChildTestPlanId); return testPlanResponses; } @@ -257,7 +424,7 @@ public class TestPlanManagementService { /** * 计划组子节点 */ - private void handChildren(List testPlanResponses, String projectId) { + private void handChildren(List testPlanResponses, List includeItemTestPlanId) { List groupIds = testPlanResponses.stream().filter(item -> StringUtils.equals(item.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)).map(TestPlanResponse::getId).toList(); if (CollectionUtils.isNotEmpty(groupIds)) { List childrenList = extTestPlanMapper.selectByGroupIds(groupIds); @@ -266,6 +433,9 @@ public class TestPlanManagementService { if (collect.containsKey(item.getId())) { //存在子节点 List list = collect.get(item.getId()); + if (CollectionUtils.isNotEmpty(includeItemTestPlanId)) { + list = list.stream().filter(child -> includeItemTestPlanId.contains(child.getId())).toList(); + } item.setChildren(list); item.setChildrenCount(list.size()); } @@ -328,8 +498,13 @@ public class TestPlanManagementService { List doneIds = new ArrayList<>(); List extraChildIds = new ArrayList<>(); // 筛选出已完成/进行中的计划或计划组 - List completePlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); - List underwayPlanOrGroupIds = selectTestPlanIdByProjectIdAndStatus(request.getProjectId(), List.of(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)); + List statusList = new ArrayList<>(); + statusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + statusList.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); + TestPlanCalculationDTO calculationDTO = this.selectTestPlanIdByProjectIdUnionConditions(request.getProjectId(), "ALL", statusList, null); + List completePlanOrGroupIds = calculationDTO.getCompletedTestPlanIds(); + List underwayPlanOrGroupIds = calculationDTO.getUnderwayTestPlanIds(); + if (CollectionUtils.isNotEmpty(completePlanOrGroupIds) || CollectionUtils.isNotEmpty(underwayPlanOrGroupIds)) { TestPlanExample example = new TestPlanExample(); example.createCriteria().andIdIn(ListUtils.union(completePlanOrGroupIds, underwayPlanOrGroupIds)); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanResourceService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanResourceService.java index 22f8eab82d..4a0e76de8f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanResourceService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanResourceService.java @@ -109,6 +109,8 @@ public abstract class TestPlanResourceService extends TestPlanSortService { public abstract List selectLastExecResultByTestPlanIds(List testPlanIds); + public abstract List selectLastExecResultByProjectId(String projectId); + /** * 关联用例 * diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java index 7960a8ea8c..7e4636d468 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanService.java @@ -1058,7 +1058,7 @@ public class TestPlanService extends TestPlanBaseUtilsService { returnDTO.unSuccessAutoIncrement(isArchived); } } else { - if (passphrase > executeRage) { + if (passphrase >= executeRage) { if (calculateList.contains(ExecStatus.PENDING.name())) { // 通过却未完成 returnDTO.passAndNotFinishedAutoIncrement(isArchived); diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/utils/TestPlanUtils.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/utils/TestPlanUtils.java new file mode 100644 index 0000000000..8064f6b795 --- /dev/null +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/utils/TestPlanUtils.java @@ -0,0 +1,30 @@ +package io.metersphere.plan.utils; + +import io.metersphere.plan.domain.TestPlan; +import io.metersphere.sdk.constants.TestPlanConstants; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TestPlanUtils { + public static Map> parseGroupIdMap(List testPlanList) { + Map> testPlanGroupIdMap = new HashMap<>(); + for (TestPlan testPlan : testPlanList) { + if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) && !testPlanGroupIdMap.containsKey(testPlan.getId())) { + testPlanGroupIdMap.put(testPlan.getId(), new ArrayList<>()); + } else { + if (testPlanGroupIdMap.containsKey(testPlan.getGroupId())) { + testPlanGroupIdMap.get(testPlan.getGroupId()).add(testPlan.getId()); + } else { + testPlanGroupIdMap.put(testPlan.getGroupId(), new ArrayList<>() {{ + this.add(testPlan.getId()); + }}); + } + } + } + return testPlanGroupIdMap; + } +} diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanControllerTests.java similarity index 86% rename from backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java rename to backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanControllerTests.java index fa5f6a7772..c5c221f7d7 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanControllerTests.java @@ -82,7 +82,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @AutoConfigureMockMvc -public class TestPlanTests extends BaseTest { +public class TestPlanControllerTests extends BaseTest { private static Project project; private static List preliminaryTreeNodes = new ArrayList<>(); @@ -145,8 +145,6 @@ public class TestPlanTests extends BaseTest { //普通测试计划 private static TestPlan simpleTestPlan; - //允许重复添加用例的测试计划 - private static TestPlan repeatCaseTestPlan; private static final String[] PROJECT_MODULE = new String[]{"workstation", "testPlan", "bugManagement", "caseManagement", "apiTest", "uiTest", "loadTest"}; @Resource @@ -156,7 +154,7 @@ public class TestPlanTests extends BaseTest { @Resource private FunctionalCaseMapper functionalCaseMapper; - private static List functionalCaseId = new ArrayList<>(); + private static final List functionalCaseId = new ArrayList<>(); @BeforeEach public void initTestData() { @@ -184,12 +182,6 @@ public class TestPlanTests extends BaseTest { } } - private static long a1NodeCount = 0; - private static long a2NodeCount = 0; - private static long a3NodeCount = 0; - private static long a1a1NodeCount = 0; - private static long a1b1NodeCount = 0; - @Test @Order(1) public void emptyDataTest() throws Exception { @@ -567,25 +559,20 @@ public class TestPlanTests extends BaseTest { if (i == 7 || i == 15 || i == 35 || i == 45 || i == 46) { request.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); } - a1NodeCount++; } else if (i < 100) { moduleId = a2Node.getId(); request.setPlannedStartTime(System.currentTimeMillis()); request.setPlannedEndTime(System.currentTimeMillis() + 20000); - a2NodeCount++; } else if (i < 150) { moduleId = a3Node.getId(); request.setRepeatCase(true); request.setAutomaticStatusUpdate(true); - a3NodeCount++; } else if (i < 200) { moduleId = a1a1Node.getId(); request.setPassThreshold((double) i / 3); request.setDescription("test plan desc " + i); - a1a1NodeCount++; } else { moduleId = a1b1Node.getId(); - a1b1NodeCount++; } //添加测试计划 @@ -666,7 +653,7 @@ public class TestPlanTests extends BaseTest { */ testPlanTestService.checkTestPlanByAddTest(); simpleTestPlan = testPlanTestService.selectTestPlanByName("testPlan_13"); - repeatCaseTestPlan = testPlanTestService.selectTestPlanByName("testPlan_123"); + // repeatCaseTestPlan = testPlanTestService.selectTestPlanByName("testPlan_123"); //在groupTestPlanId7、groupTestPlanId15下面各创建20条数据(并且校验第21条不能创建成功) for (int i = 0; i < 21; i++) { @@ -886,6 +873,7 @@ public class TestPlanTests extends BaseTest { Assertions.assertTrue(tableList.get(1).getId().equals(posRequest.getMoveId())); Assertions.assertTrue(tableList.get(2).getId().equals(posRequest.getTargetId())); } + protected void checkTestPlanSortInGroup(String groupId) throws Exception { /* 排序校验用例设计: @@ -1111,94 +1099,299 @@ public class TestPlanTests extends BaseTest { onlyPlanRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); - //进行状态筛选 -- 空状态 - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 999 - 1); + /* 现有数据状态: - 已完成的 6 47(组) - 进行中的 16 - 已归档的 35(组) + 已完成的测试计划: 6 + 已完成的测试计划组: 46(组) + 进行中的测试计划: 16 + 没有测试子计划的组: 45 + 已归档的1个: 35(组) */ - //进行状态筛选 -- 未开始 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 999 - 1 - 1 - 2); - //进行状态筛选 -- 已完成 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 2); - //进行状态筛选 -- 进行中 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 1); - //进行状态筛选 -- 已完成和未开始 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", new ArrayList() {{ - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + int finishedPlan = 1; + int finishedGroup = 1; + int underwayPlan = 1; + int noPlanGroup = 1; + int archivedPlan = 1; + + int testPlanCount = 994; + int testPlanGroupCount = 5; + + // 测试通过 + { + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)); }}); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 999 - 1 - 1); - //进行状态筛选 -- 已完成和进行中 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", new ArrayList() {{ - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan + finishedGroup); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedGroup); + } + //测试不通过 + { + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_NOT_PASSED)); }}); - }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount + testPlanGroupCount - archivedPlan - finishedPlan - finishedGroup); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount - finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount - archivedPlan - finishedGroup); + } + + //进行状态筛选 -- 空状态 + statusRequest.setType("ALL"); + statusRequest.setFilter(null); testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), dataRequest.getCurrent(), dataRequest.getPageSize(), - 3); - //进行状态筛选 -- 进行中和未开始 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", new ArrayList() {{ - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + testPlanCount + testPlanGroupCount - archivedPlan); + + + //进行状态筛选 -- 未开始 (并且检查不同的tab页 + { + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED)); }}); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 999 - 1 - 2); - //进行状态筛选 -- 已完成、未开始、进行中 - statusRequest.setFilter(new HashMap<>() {{ - this.put("status", new ArrayList() {{ - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); - this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount + testPlanGroupCount - archivedPlan - underwayPlan - finishedPlan - finishedGroup); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount - underwayPlan - finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount - archivedPlan - finishedGroup); + } + { + //进行状态筛选 -- 已完成 + statusRequest.setType("ALL"); + + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); }}); - }}); - testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( - URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), - dataRequest.getCurrent(), - dataRequest.getPageSize(), - 999 - 1); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan + finishedGroup); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedGroup); + + } + { + //进行状态筛选 -- 进行中 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY)); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + underwayPlan); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + underwayPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + 0); + } + + { + //进行状态筛选 已完成和未开始 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", new ArrayList() {{ + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + }}); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount + testPlanGroupCount - archivedPlan - underwayPlan); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount - underwayPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount - archivedPlan); + + //配合状态进行筛选 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED)); + this.put("passed", Collections.singletonList(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PASSED)); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan + finishedGroup); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedGroup); + } + { + //进行状态筛选 -- 已完成和进行中 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", new ArrayList() {{ + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); + }}); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan + finishedGroup + underwayPlan); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedPlan + underwayPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + finishedGroup); + } + { + //进行状态筛选 -- 进行中和未开始 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", new ArrayList() {{ + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + }}); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount + testPlanGroupCount - archivedPlan - finishedPlan - finishedGroup); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount - finishedPlan); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount - archivedPlan - finishedGroup); + } + { + //进行状态筛选 -- 已完成、未开始、进行中 + statusRequest.setType("ALL"); + statusRequest.setFilter(new HashMap<>() {{ + this.put("status", new ArrayList() {{ + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_UNDERWAY); + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_PREPARED); + this.add(TestPlanConstants.TEST_PLAN_SHOW_STATUS_COMPLETED); + }}); + }}); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount + testPlanCount - archivedPlan); + + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanCount); + statusRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP); + testPlanTestService.checkTestPlanPage(this.requestPostWithOkAndReturn( + URL_POST_TEST_PLAN_PAGE, statusRequest).getResponse().getContentAsString(StandardCharsets.UTF_8), + dataRequest.getCurrent(), + dataRequest.getPageSize(), + testPlanGroupCount - archivedPlan); + } + + statusRequest.setType("ALL"); BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1"); BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2"); @@ -1438,11 +1631,9 @@ public class TestPlanTests extends BaseTest { updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_91").getId()); updateRequest.setGroupId(groupTestPlanId45); this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest); - a2NodeCount--; updateRequest = testPlanTestService.generateUpdateRequest(testPlanTestService.selectTestPlanByName("testPlan_92").getId()); updateRequest.setGroupId(groupTestPlanId45); this.requestPostWithOk(URL_POST_TEST_PLAN_UPDATE, updateRequest); - a2NodeCount--; TestPlan updatePlan = new TestPlan(); updatePlan.setId(groupTestPlanId7); @@ -2238,29 +2429,29 @@ public class TestPlanTests extends BaseTest { } - private void checkModuleCount(Map moduleCountMap, long a1NodeCount, long a2NodeCount, long a3NodeCount, long a1a1NodeCount, long a1b1NodeCount) throws Exception { - BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1"); - BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2"); - BaseTreeNode a3Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a3"); - BaseTreeNode a1a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-a1"); - BaseTreeNode a1b1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-b1"); - assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null; - //检查每个节点下的数据是否匹配的上(父节点的统计会一并添加上子节点的数据) - moduleCountMap.forEach((k, v) -> { - long value = Long.parseLong(String.valueOf(v)); - if (StringUtils.equals(k, a1Node.getId())) { - Assertions.assertEquals(value, a1NodeCount + a1a1NodeCount + a1b1NodeCount); - } else if (StringUtils.equals(k, a2Node.getId())) { - Assertions.assertEquals(value, a2NodeCount); - } else if (StringUtils.equals(k, a3Node.getId())) { - Assertions.assertEquals(value, a3NodeCount); - } else if (StringUtils.equals(k, a1a1Node.getId())) { - Assertions.assertEquals(value, a1a1NodeCount); - } else if (StringUtils.equals(k, a1b1Node.getId())) { - Assertions.assertEquals(value, a1b1NodeCount); - } - }); - } + // private void checkModuleCount(Map moduleCountMap, long a1NodeCount, long a2NodeCount, long a3NodeCount, long a1a1NodeCount, long a1b1NodeCount) throws Exception { + // BaseTreeNode a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1"); + // BaseTreeNode a2Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a2"); + // BaseTreeNode a3Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a3"); + // BaseTreeNode a1a1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-a1"); + // BaseTreeNode a1b1Node = TestPlanTestUtils.getNodeByName(preliminaryTreeNodes, "a1-b1"); + // assert a1Node != null & a2Node != null & a3Node != null & a1a1Node != null & a1b1Node != null; + // //检查每个节点下的数据是否匹配的上(父节点的统计会一并添加上子节点的数据) + // moduleCountMap.forEach((k, v) -> { + // long value = Long.parseLong(String.valueOf(v)); + // if (StringUtils.equals(k, a1Node.getId())) { + // Assertions.assertEquals(value, a1NodeCount + a1a1NodeCount + a1b1NodeCount); + // } else if (StringUtils.equals(k, a2Node.getId())) { + // Assertions.assertEquals(value, a2NodeCount); + // } else if (StringUtils.equals(k, a3Node.getId())) { + // Assertions.assertEquals(value, a3NodeCount); + // } else if (StringUtils.equals(k, a1a1Node.getId())) { + // Assertions.assertEquals(value, a1a1NodeCount); + // } else if (StringUtils.equals(k, a1b1Node.getId())) { + // Assertions.assertEquals(value, a1b1NodeCount); + // } + // }); + // } @Resource private TestPlanService testPlanService; @@ -2541,9 +2732,12 @@ public class TestPlanTests extends BaseTest { testPlanService.deletePlanCollectionResource(List.of("init_collection-delete-1", "init_collection-delete-2", "init_collection-delete-3")); } + /** + * 方法层面的测试 + */ @Test @Order(310) - void testStatusSelectMethod() { + void testForFunctions() { //initSQL中,功能用例id:oasis_fc_1 的数据关联到了测试计划 List testPlanStatusList = new ArrayList<>(); testPlanStatusList.add(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED); @@ -2595,6 +2789,8 @@ public class TestPlanTests extends BaseTest { Assertions.assertEquals(1, underwayTestPlanIds.size()); Assertions.assertEquals("test3", underwayTestPlanIds.getFirst()); + + testPlanManagementService.selectTestPlanIdByProjectIdUnionConditions(null, null, null, null); } }