From f2312e8da8d11bbceb7ec7b6d10f2d9a2f1b12b2 Mon Sep 17 00:00:00 2001 From: Jianguo-Genius Date: Thu, 24 Oct 2024 14:38:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B5=8B=E8=AF=95=E8=AE=A1=E5=88=92):=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B5=8B=E8=AF=95=E7=B1=BB=E5=9E=8B=E7=9A=84?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E5=81=9C=E6=AD=A2=E5=92=8C=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E9=9B=86=E7=9A=84=E5=A4=B1=E8=B4=A5=E5=81=9C=E6=AD=A2=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=86=B2=E7=AA=81=E6=97=B6=E7=9A=84=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E5=81=9C=E6=AD=A2=E6=94=AF=E6=8C=81&=E5=9C=BA=E6=99=AF?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E7=9A=84=E9=A1=B5=E9=9D=A2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1047945 --user=宋天阳 【测试计划】-场景串行+失败停止,测试点A串行+失败不停止,测试点B并行,执行后,测试点2的场景全部执行了 https://www.tapd.cn/55049933/s/1597277 --- .../ApiScenarioBatchExportRequest.java | 2 ++ .../ApiScenarioDataTransferService.java | 12 +++---- .../ApiDefinitionExportService.java | 6 ++-- .../mapper/ExtTestPlanCollectionMapper.java | 3 ++ .../mapper/ExtTestPlanCollectionMapper.xml | 6 ++++ .../ExtTestPlanReportApiCaseMapper.java | 2 ++ .../mapper/ExtTestPlanReportApiCaseMapper.xml | 6 ++++ .../ExtTestPlanReportApiScenarioMapper.java | 2 ++ .../ExtTestPlanReportApiScenarioMapper.xml | 6 ++++ .../plan/service/TestPlanExecuteService.java | 31 +++++++++++++++-- frontend/src/enums/apiEnum.ts | 5 --- frontend/src/models/apiTest/scenario.ts | 1 + .../exportScenario/scenarioExportModal.vue | 33 ++++++++++--------- .../views/api-test/scenario/locale/en-US.ts | 3 +- .../views/api-test/scenario/locale/zh-CN.ts | 3 +- 15 files changed, 88 insertions(+), 33 deletions(-) diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiScenarioBatchExportRequest.java b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiScenarioBatchExportRequest.java index 3122fde2e6..0296707859 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiScenarioBatchExportRequest.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/dto/definition/ApiScenarioBatchExportRequest.java @@ -31,6 +31,8 @@ public class ApiScenarioBatchExportRequest extends ApiScenarioBatchRequest imple @Schema(description = "排序字段(model中的字段 : asc/desc)") private Map<@Valid @Pattern(regexp = "^[A-Za-z]+$") String, @Valid @NotBlank String> sort; + private boolean exportAllRelatedData; + public String getSortString() { if (sort == null || sort.isEmpty()) { return null; diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioDataTransferService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioDataTransferService.java index 4c49b88ce5..1440918997 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioDataTransferService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/ApiScenarioDataTransferService.java @@ -1,7 +1,6 @@ package io.metersphere.api.service; import io.metersphere.api.constants.ApiDefinitionStatus; -import io.metersphere.api.constants.ApiScenarioExportType; import io.metersphere.api.constants.ApiScenarioStepType; import io.metersphere.api.domain.*; import io.metersphere.api.dto.ApiFile; @@ -76,6 +75,7 @@ import java.io.File; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.util.stream.Collectors; @@ -1023,11 +1023,11 @@ public class ApiScenarioDataTransferService { Map moduleMap = this.apiScenarioModuleService.getTree(request.getProjectId()).stream().collect(Collectors.toMap(BaseTreeNode::getId, BaseTreeNode::getPath)); String fileFolder = tmpDir.getPath() + File.separatorChar + request.getFileId(); - int fileIndex = 1; + AtomicInteger fileIndex = new AtomicInteger(1); SubListUtils.dealForSubList(ids, 500, subList -> { request.setSelectIds(subList); - ApiScenarioExportResponse exportResponse = this.genMetersphereExportResponse(request, moduleMap, exportType, userId); - TempFileUtils.writeExportFile(fileFolder + File.separatorChar + "scenario_export_" + fileIndex + ".ms", exportResponse); + ApiScenarioExportResponse exportResponse = this.genMetersphereExportResponse(request, moduleMap); + TempFileUtils.writeExportFile(fileFolder + File.separatorChar + "scenario_" + fileIndex.getAndIncrement() + ".ms", exportResponse); }); File zipFile = MsFileUtils.zipFile(tmpDir.getPath(), request.getFileId()); if (zipFile == null) { @@ -1058,13 +1058,13 @@ public class ApiScenarioDataTransferService { } } - private ApiScenarioExportResponse genMetersphereExportResponse(ApiScenarioBatchExportRequest request, Map moduleMap, String exportType, String userId) { + private ApiScenarioExportResponse genMetersphereExportResponse(ApiScenarioBatchExportRequest request, Map moduleMap) { Project project = projectMapper.selectByPrimaryKey(request.getProjectId()); MetersphereApiScenarioExportResponse response = apiScenarioService.selectAndSortScenarioDetailWithIds(request.getSelectIds(), moduleMap); response.setProjectId(project.getId()); response.setOrganizationId(project.getOrganizationId()); - if (StringUtils.equalsIgnoreCase(ApiScenarioExportType.METERSPHERE_ALL_DATA.name(), exportType)) { + if (request.isExportAllRelatedData()) { // 全量导出,导出引用的api、apiCase List apiDefinitionIdList = new ArrayList<>(); List apiCaseIdList = new ArrayList<>(); diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionExportService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionExportService.java index 0930803a6e..fb93af927a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionExportService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiDefinitionExportService.java @@ -39,6 +39,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -133,11 +134,12 @@ public class ApiDefinitionExportService { Map moduleMap = this.buildModuleIdPathMap(request.getProjectId()); String fileFolder = tmpDir.getPath() + File.separatorChar + request.getFileId(); - int fileIndex = 1; + + AtomicInteger fileIndex = new AtomicInteger(1); SubListUtils.dealForSubList(ids, 1000, subList -> { request.setSelectIds(subList); ApiDefinitionExportResponse exportResponse = this.genApiExportResponse(request, moduleMap, exportType, userId); - TempFileUtils.writeExportFile(fileFolder + File.separatorChar + fileIndex + ".json", exportResponse); + TempFileUtils.writeExportFile(fileFolder + File.separatorChar + "API_" + fileIndex.getAndIncrement() + ".json", exportResponse); }); File zipFile = MsFileUtils.zipFile(tmpDir.getPath(), request.getFileId()); if (zipFile == null) { diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.java index c355b57c5e..2d13e3ce1e 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.java @@ -1,5 +1,6 @@ package io.metersphere.plan.mapper; +import io.metersphere.plan.domain.TestPlanCollection; import io.metersphere.plan.dto.TestPlanCollectionConfigDTO; import io.metersphere.plan.dto.TestPlanCollectionEnvDTO; import org.apache.ibatis.annotations.Param; @@ -17,4 +18,6 @@ public interface ExtTestPlanCollectionMapper { String selectDefaultCollectionId(@Param("testPlanId")String newTestPlanId,@Param("type") String key); boolean getParentStopOnFailure(String collectionId); + + List selectByItemParentId(String collectionId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.xml index f986b3d667..9309e98d27 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanCollectionMapper.xml @@ -64,4 +64,10 @@ from test_plan_collection where id IN (select parent_id from test_plan_collection where id = #{0}) + \ No newline at end of file diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.java index acfd8dbcf5..5e798be6b1 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.java @@ -50,4 +50,6 @@ public interface ExtTestPlanReportApiCaseMapper { List listCollection(@Param("request") TestPlanReportDetailPageRequest request); List getIdsByReportIdAndCollectionId(@Param("testPlanReportId") String testPlanReportId, @Param("collectionId") String collectionId); + + List selectExecResultByReportIdAndCollectionId(@Param("collectionId") String collectionId, @Param("reportId") String prepareReportId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.xml index 03fefbcdb4..5ad257e95a 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiCaseMapper.xml @@ -78,6 +78,12 @@ and atc.deleted = false order by tpac.pos desc + diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.java index 9341185ce1..21bbb7ba06 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.java @@ -49,4 +49,6 @@ public interface ExtTestPlanReportApiScenarioMapper { * @return 关联的测试集集合 */ List listCollection(@Param("request") TestPlanReportDetailPageRequest request); + + List selectExecResultByReportIdAndCollectionId(@Param("collectionId") String collectionId, @Param("reportId") String prepareReportId); } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.xml b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.xml index 8c77564435..d69d93e72f 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.xml +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/mapper/ExtTestPlanReportApiScenarioMapper.xml @@ -71,6 +71,12 @@ and aso.deleted = false order by tpas.pos desc + diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java index 543f079fc6..26ce6715a8 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanExecuteService.java @@ -5,6 +5,7 @@ import io.metersphere.api.domain.ApiReportRelateTask; import io.metersphere.api.mapper.ApiReportRelateTaskMapper; import io.metersphere.api.service.ApiBatchRunBaseService; import io.metersphere.api.service.ApiCommonService; +import io.metersphere.functional.constants.AssociateCaseType; import io.metersphere.plan.domain.*; import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest; import io.metersphere.plan.dto.request.TestPlanExecuteRequest; @@ -30,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import static io.metersphere.plan.service.TestPlanExecuteSupportService.*; @@ -56,6 +58,10 @@ public class TestPlanExecuteService { @Resource private TestPlanApiBatchRunBaseService testPlanApiBatchRunBaseService; + @Resource + private ExtTestPlanReportApiCaseMapper extTestPlanReportApiCaseMapper; + @Resource + private ExtTestPlanReportApiScenarioMapper extTestPlanReportApiScenarioMapper; @Resource private TestPlanReportMapper testPlanReportMapper; @Resource @@ -642,7 +648,7 @@ public class TestPlanExecuteService { this.executeByTestPlanCollection(queue); } else if (StringUtils.equalsIgnoreCase(queue.getQueueType(), QUEUE_PREFIX_TEST_PLAN_COLLECTION)) { // 判断是否是失败停止。 如果是失败停止,要检测父类是否也同样配置了失败停止。是的话,不再执行。 - if (this.isCaseTypeExecuteStop(queue.getSourceID(), isStopOnFailure)) { + if (this.isCaseTypeExecuteStop(queue.getSourceID(), queue.getPrepareReportId(), isStopOnFailure)) { this.collectionExecuteQueueFinish(queue.getQueueId(), isStopOnFailure); } else { this.executeCase(queue); @@ -650,10 +656,31 @@ public class TestPlanExecuteService { } } - private boolean isCaseTypeExecuteStop(String collectionId, boolean isStopOnFailure) { + private boolean isCaseTypeExecuteStop(String collectionId, String prepareReportId, boolean isStopOnFailure) { boolean caseTypeStopOnFailure = extTestPlanCollectionMapper.getParentStopOnFailure(collectionId); + // 如果测试集是失败停止触发的,通过父类的配置决定是否执行结束。 if (isStopOnFailure) { return caseTypeStopOnFailure; + } else if (caseTypeStopOnFailure) { + // 如果是正常执行结束的,并且配置了失败停止,则根据该测试集的执行结果是否全部成功,来决定是否继续执行 + + //首先拿到执行结束的测试集 + List testPlanCollectionList = extTestPlanCollectionMapper.selectByItemParentId(collectionId); + TestPlanCollection lastCollection = null; + for (TestPlanCollection item : testPlanCollectionList) { + if (StringUtils.equalsIgnoreCase(item.getId(), collectionId)) { + break; + } + lastCollection = item; + } + + List execResult = null; + if (AssociateCaseType.API.equals(lastCollection.getType())) { + execResult = extTestPlanReportApiCaseMapper.selectExecResultByReportIdAndCollectionId(lastCollection.getId(), prepareReportId); + } else if (AssociateCaseType.SCENARIO.equals(lastCollection.getType())) { + execResult = extTestPlanReportApiScenarioMapper.selectExecResultByReportIdAndCollectionId(lastCollection.getId(), prepareReportId); + } + return CollectionUtils.size(execResult) != 1 || !StringUtils.equalsIgnoreCase(Objects.requireNonNull(execResult).getFirst(), ResultStatus.SUCCESS.name()); } else { return false; } diff --git a/frontend/src/enums/apiEnum.ts b/frontend/src/enums/apiEnum.ts index a31e21d345..5fbb10a422 100644 --- a/frontend/src/enums/apiEnum.ts +++ b/frontend/src/enums/apiEnum.ts @@ -257,11 +257,6 @@ export enum ScenarioExecuteStatus { FAKE_ERROR = 'FAKE_ERROR', } -// 场景导出配置 -export enum ScenarioExportType { - SIMPLE = 'METERSPHERE_SIMPLE', - ALL = 'METERSPHERE_ALL_DATA', -} // 场景步骤类型 export enum ScenarioStepType { API_CASE = 'API_CASE', // 接口用例 diff --git a/frontend/src/models/apiTest/scenario.ts b/frontend/src/models/apiTest/scenario.ts index d111c0ba72..0ebfab0a4f 100644 --- a/frontend/src/models/apiTest/scenario.ts +++ b/frontend/src/models/apiTest/scenario.ts @@ -548,5 +548,6 @@ export interface ImportScenarioParams { // 导出场景参数 export interface ExportScenarioParams extends BatchActionQueryParams { apiScenarioId: string; + exportAllRelatedData: boolean; fileId: string; } diff --git a/frontend/src/views/api-test/scenario/components/common/exportScenario/scenarioExportModal.vue b/frontend/src/views/api-test/scenario/components/common/exportScenario/scenarioExportModal.vue index d9b4981b94..a3e3f37db7 100644 --- a/frontend/src/views/api-test/scenario/components/common/exportScenario/scenarioExportModal.vue +++ b/frontend/src/views/api-test/scenario/components/common/exportScenario/scenarioExportModal.vue @@ -6,18 +6,20 @@ class="ms-modal-upload ms-modal-medium" :width="400" > - - {{ t('apiScenario.export.type.simple') }} - - - - - {{ t('apiScenario.export.type.all') }} - +
+ + {{ t('apiScenario.export.type.all') }} + + + + +