From 3a50a38ceccf8a73c9bd011e7571bb6b69f8f0c4 Mon Sep 17 00:00:00 2001 From: song-tianyang Date: Tue, 21 Mar 2023 11:33:01 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E6=B5=8B=E8=AF=95=E8=B7=9F=E8=B8=AA):=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92=E5=85=B3?= =?UTF-8?q?=E8=81=94=E5=9C=BA=E6=99=AF=E6=97=B6=E5=85=A8=E9=80=89=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=EF=BC=8C=E8=BF=90=E8=A1=8C=E7=8E=AF=E5=A2=83=E4=B8=AD?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=98=BE=E7=A4=BA=E4=B8=8D=E5=85=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1024678 --user=宋天阳 [测试跟踪]github#22858测试计划中添加场景用例,全选所有场景(不止一页数据),非当前页的某个场景含多个项目运行环境时,在测试计划中选择环境时无法选择多个项目环境,导致执行测试计划时一直running https://www.tapd.cn/55049933/s/1353537 --- .../base/mapper/ext/ExtApiScenarioMapper.java | 2 + .../base/mapper/ext/ExtApiScenarioMapper.xml | 13 ++++- .../commons/utils/BatchProcessingUtil.java | 28 ++++++++++ .../plan/TestPlanScenarioCaseController.java | 5 ++ .../plan/TestPlanScenarioCaseService.java | 8 +++ .../service/scenario/ApiScenarioService.java | 33 ++++++++++++ .../src/api/remote/plan/test-plan-scenario.js | 24 +++++---- .../comonents/api/RelevanceScenarioList.vue | 52 +++++++++++++------ 8 files changed, 138 insertions(+), 27 deletions(-) diff --git a/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java b/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java index b4f9728dd2..38741f0cdd 100644 --- a/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java +++ b/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.java @@ -85,4 +85,6 @@ public interface ExtApiScenarioMapper { List selectScenarioIdInExecutionInfoByProjectIdIsNull(); long countSourceIdByProjectIdIsNull(); + + List selectIdByScenarioRequest(@Param("request") ApiScenarioRequest request); } diff --git a/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml b/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml index 06d0a2998c..730fbb9486 100644 --- a/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml +++ b/api-test/backend/src/main/java/io/metersphere/base/mapper/ext/ExtApiScenarioMapper.xml @@ -1035,5 +1035,16 @@ FROM scenario_execution_info WHERE project_id IS NULL - + diff --git a/api-test/backend/src/main/java/io/metersphere/commons/utils/BatchProcessingUtil.java b/api-test/backend/src/main/java/io/metersphere/commons/utils/BatchProcessingUtil.java index 8def4bce25..2e11c49bf3 100644 --- a/api-test/backend/src/main/java/io/metersphere/commons/utils/BatchProcessingUtil.java +++ b/api-test/backend/src/main/java/io/metersphere/commons/utils/BatchProcessingUtil.java @@ -16,6 +16,34 @@ public class BatchProcessingUtil { private static final int BATCH_PROCESS_QUANTITY = 1000; + public static List getProjectIdsByScenarioIdList(List scenarioIdList, Function, List> func) { + List returnList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(scenarioIdList)) { + int unProcessingCount = scenarioIdList.size(); + while (scenarioIdList.size() > BATCH_PROCESS_QUANTITY) { + List processingList = new ArrayList<>(); + for (int i = 0; i < BATCH_PROCESS_QUANTITY; i++) { + processingList.add(scenarioIdList.get(i)); + } + //函数处理 + returnList.addAll(func.apply(processingList)); + scenarioIdList.removeAll(processingList); + + //如果剩余数量没有发生变化,则跳出循环。防止出现死循环的情况 + if (scenarioIdList.size() == unProcessingCount) { + break; + } else { + unProcessingCount = scenarioIdList.size(); + } + } + if (CollectionUtils.isNotEmpty(scenarioIdList)) { + //剩余待处理数据进行处理 + returnList.addAll(func.apply(scenarioIdList)); + } + } + return returnList; + } + public static List selectScenarioReportResultByScenarioReportId(List scenarioReportId, Function, List> func) { List returnList = new ArrayList<>(); if (CollectionUtils.isNotEmpty(scenarioReportId)) { diff --git a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java index 80f3739414..3a269f7544 100644 --- a/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java +++ b/api-test/backend/src/main/java/io/metersphere/controller/plan/TestPlanScenarioCaseController.java @@ -78,6 +78,11 @@ public class TestPlanScenarioCaseController { return testPlanScenarioCaseService.relevanceList(request, goPage, pageSize); } + @PostMapping("/relevance/projectIds") + public List relevanceProjectIds(@RequestBody ApiScenarioRequest request) { + return testPlanScenarioCaseService.relevanceProjectIds(request); + } + @PostMapping("/relevance") @MsAuditLog(module = OperLogModule.TRACK_TEST_PLAN, type = OperLogConstants.ASSOCIATE_CASE, content = "#msClass.getLogDetails(#request)", msClass = ApiScenarioService.class) public void testPlanRelevance(@RequestBody ApiCaseRelevanceRequest request) { diff --git a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java index aef5b082fd..8b61c91d66 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/plan/TestPlanScenarioCaseService.java @@ -178,6 +178,14 @@ public class TestPlanScenarioCaseService { return PageUtils.setPageInfo(page, apiAutomationService.list(request)); } + public List relevanceProjectIds(ApiScenarioRequest request) { + request.setNotInTestPlan(true); + if (request.getAllowedRepeatCase()) { + request.setNotInTestPlan(false); + } + return apiAutomationService.projectIdInlist(request); + } + public void relevance(ApiCaseRelevanceRequest request) { if (request.getAllowedRepeatCase()) { request.getCondition().setNotInTestPlan(false); diff --git a/api-test/backend/src/main/java/io/metersphere/service/scenario/ApiScenarioService.java b/api-test/backend/src/main/java/io/metersphere/service/scenario/ApiScenarioService.java index c56cff9833..36b91fe7e7 100644 --- a/api-test/backend/src/main/java/io/metersphere/service/scenario/ApiScenarioService.java +++ b/api-test/backend/src/main/java/io/metersphere/service/scenario/ApiScenarioService.java @@ -2308,4 +2308,37 @@ public class ApiScenarioService { return scenarioList.get(0); } } + + public List projectIdInlist(ApiScenarioRequest request) { + request = this.initRequest(request, true, true); + List scenarioIdList = extApiScenarioMapper.selectIdByScenarioRequest(request); + if (CollectionUtils.isNotEmpty(request.getUnSelectIds())) { + scenarioIdList.removeAll(request.getUnSelectIds()); + } + List projectIdList = BatchProcessingUtil.getProjectIdsByScenarioIdList(scenarioIdList, this::getProjectIdsByScenarioIdList); + + return projectIdList; + } + + public List getProjectIdsByScenarioIdList(List scenarioIdList) { + List projectIdList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(scenarioIdList)) { + ApiScenarioExample example = new ApiScenarioExample(); + example.createCriteria().andIdIn(scenarioIdList); + List scenarioWithBLOBsList = apiScenarioMapper.selectByExampleWithBLOBs(example); + for (ApiScenarioWithBLOBs scenario : scenarioWithBLOBsList) { + ScenarioEnv scenarioEnv = apiScenarioEnvService.getApiScenarioEnv(scenario.getScenarioDefinition()); + if (CollectionUtils.isNotEmpty(scenarioEnv.getProjectIds())) { + scenarioEnv.getProjectIds().forEach(projectId -> { + if (!projectIdList.contains(projectId)) { + projectIdList.add(projectId); + } + }); + } + } + } + return projectIdList; + } + + } diff --git a/test-track/frontend/src/api/remote/plan/test-plan-scenario.js b/test-track/frontend/src/api/remote/plan/test-plan-scenario.js index 51245fa1d0..3b13e27135 100644 --- a/test-track/frontend/src/api/remote/plan/test-plan-scenario.js +++ b/test-track/frontend/src/api/remote/plan/test-plan-scenario.js @@ -1,39 +1,43 @@ -import {post, get} from "@/business/utils/sdk-utils"; -import {buildListPagePath, buildPagePath} from "@/api/base-network"; +import { get, post } from "@/business/utils/sdk-utils"; +import { buildListPagePath, buildPagePath } from "@/api/base-network"; -const BASE_URL = '/test/plan/scenario/case/'; +const BASE_URL = "/test/plan/scenario/case/"; export function testPlanScenarioList(page, param) { return post(BASE_URL + buildListPagePath(page), param); } export function scenarioRelevanceList(page, param) { - page.path = 'relevance/list'; + page.path = "relevance/list"; return post(BASE_URL + buildPagePath(page), param); } +export function scenarioRelevanceProjectIds(param) { + return post(BASE_URL + "relevance/projectIds", param); +} + export function scenarioRelevance(param) { - return post(BASE_URL + 'relevance', param); + return post(BASE_URL + "relevance", param); } export function testPlanScenarioEnv(param) { - return post(BASE_URL + 'env', param); + return post(BASE_URL + "env", param); } export function testPlanScenarioCaseBatchUpdateEnv(param) { - return post(BASE_URL + 'batch/update/env', param); + return post(BASE_URL + "batch/update/env", param); } export function testPlanScenarioCaseRun(param) { - return post(BASE_URL + 'run', param); + return post(BASE_URL + "run", param); } export function testPlanScenarioCaseBatchDelete(param) { - return post(BASE_URL + 'batch/delete', param); + return post(BASE_URL + "batch/delete", param); } export function testPlanScenarioCaseSelectAllTableRows(param) { - return post(BASE_URL + 'select-rows', param); + return post(BASE_URL + "select-rows", param); } export function testPlanScenarioCaseDelete(id) { diff --git a/test-track/frontend/src/business/plan/view/comonents/api/RelevanceScenarioList.vue b/test-track/frontend/src/business/plan/view/comonents/api/RelevanceScenarioList.vue index 2f02fbb369..cd4758a54b 100644 --- a/test-track/frontend/src/business/plan/view/comonents/api/RelevanceScenarioList.vue +++ b/test-track/frontend/src/business/plan/view/comonents/api/RelevanceScenarioList.vue @@ -67,7 +67,7 @@ prop="name" :label="$t('api_test.automation.scenario_name')" sortable="custom" - min-width="100px" + min-width="120px" show-overflow-tooltip /> @@ -141,6 +144,7 @@ prop="lastResult" :label="$t('api_test.automation.last_result')" sortable="custom" + min-width="120px" >