From 573bcca5121ae7bc511a8bef3045c72121d4f7a0 Mon Sep 17 00:00:00 2001 From: zhangdahai112 Date: Thu, 8 Sep 2022 18:15:23 +0800 Subject: [PATCH] =?UTF-8?q?fix(UI=20=E8=87=AA=E5=8A=A8=E5=8C=96):=20UI?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=8E=87=E8=AE=A1=E7=AE=97=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1016623 --user=张大海 【UI测试】当成功的步骤为0时-通过率计算错误 https://www.tapd.cn/55049933/s/1240952a --- .../api/service/ApiScenarioReportService.java | 6 +- .../api/service/utils/PassRateUtil.java | 65 ++++++++----------- 2 files changed, 30 insertions(+), 41 deletions(-) diff --git a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java index da4e019b03..e466a612ea 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiScenarioReportService.java @@ -124,7 +124,7 @@ public class ApiScenarioReportService { } else if (dto.getRunMode().startsWith("UI")) { ApiScenarioReportResultExample example = new ApiScenarioReportResultExample(); example.createCriteria().andReportIdEqualTo(dto.getReportId()); - scenarioReport = updateUiScenario(apiScenarioReportResultMapper.selectByExample(example), dto); + scenarioReport = updateUiScenario(apiScenarioReportResultMapper.selectByExampleWithBLOBs(example), dto); } else { scenarioReport = updateScenario(dto); } @@ -484,7 +484,7 @@ public class ApiScenarioReportService { return report; } - public ApiScenarioReport updateUiScenario(List requestResults, ResultDTO dto) { + public ApiScenarioReport updateUiScenario(List requestResults, ResultDTO dto) { long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count(); // 更新报告状态 String status = getStatus(dto); @@ -525,7 +525,7 @@ public class ApiScenarioReportService { } @Nullable - private boolean updateUiScenario(List requestResults, ResultDTO dto, long errorSize, String status, ApiScenarioReport report, UiScenarioWithBLOBs scenario) { + private boolean updateUiScenario(List requestResults, ResultDTO dto, long errorSize, String status, ApiScenarioReport report, UiScenarioWithBLOBs scenario) { if (StringUtils.equalsAnyIgnoreCase(status, ExecuteResult.UN_EXECUTE.toString())) { scenario.setLastResult(ScenarioStatus.Fail.name()); } else { diff --git a/backend/src/main/java/io/metersphere/api/service/utils/PassRateUtil.java b/backend/src/main/java/io/metersphere/api/service/utils/PassRateUtil.java index 031a10a4d8..13ec673cdc 100644 --- a/backend/src/main/java/io/metersphere/api/service/utils/PassRateUtil.java +++ b/backend/src/main/java/io/metersphere/api/service/utils/PassRateUtil.java @@ -3,10 +3,8 @@ package io.metersphere.api.service.utils; import com.alibaba.fastjson.JSONArray; import io.metersphere.api.dto.StepTreeDTO; import io.metersphere.api.dto.automation.ScenarioStatus; -import io.metersphere.base.domain.ApiScenarioReport; -import io.metersphere.base.domain.ApiScenarioReportResult; -import io.metersphere.base.domain.ApiScenarioReportStructureExample; -import io.metersphere.base.domain.ApiScenarioReportStructureWithBLOBs; +import io.metersphere.api.service.ApiScenarioReportStructureService; +import io.metersphere.base.domain.*; import io.metersphere.base.mapper.ApiScenarioReportStructureMapper; import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.constants.SystemConstants; @@ -28,31 +26,35 @@ import java.util.stream.Collectors; */ public class PassRateUtil { - public static String calculatePassRate(List requestResults, ApiScenarioReport report) { + private final static String ZERO_PERCENT = "0%"; + public static final String UNEXECUTE = "unexecute"; + + public static String calculatePassRate(List requestResults, ApiScenarioReport report) { if (CollectionUtils.isEmpty(requestResults)) { - return "0"; + return ZERO_PERCENT; } else { long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count(); if (report.getReportType().startsWith(SystemConstants.TestTypeEnum.UI.name())) { //resourceId -> 结果列表 循环可能一个 resourceId 对应多个接口 - Map> resultResourceStatusMap = requestResults.stream().collect(Collectors.groupingBy(ApiScenarioReportResult::getResourceId)); + Map> resultResourceStatusMap = requestResults.stream().collect(Collectors.groupingBy(ApiScenarioReportResult::getResourceId)); ApiScenarioReportStructureExample e = new ApiScenarioReportStructureExample(); e.createCriteria().andReportIdEqualTo(report.getId()); List apiScenarioReportStructures = CommonBeanFactory.getBean(ApiScenarioReportStructureMapper.class).selectByExampleWithBLOBs(e); if (CollectionUtils.isEmpty(apiScenarioReportStructures)) { - return "0"; + return ZERO_PERCENT; } List stepList = JSONArray.parseArray(new String(apiScenarioReportStructures.get(0).getResourceTree(), StandardCharsets.UTF_8), StepTreeDTO.class); - successSize = getUISuccessSize(resultResourceStatusMap, stepList); + ((ApiScenarioReportStructureService) CommonBeanFactory.getBean("apiScenarioReportStructureService")).reportFormatting(stepList, resultResourceStatusMap, "UI"); + successSize = getUISuccessSize(stepList); if (CollectionUtils.isEmpty(stepList)) { - return "0"; + return ZERO_PERCENT; } - return new DecimalFormat("0%").format((float) successSize / getTotalSteps(stepList)); + return new DecimalFormat(ZERO_PERCENT).format((float) successSize / getTotalSteps(stepList)); } else { - return new DecimalFormat("0%").format((float) successSize / requestResults.size()); + return new DecimalFormat(ZERO_PERCENT).format((float) successSize / requestResults.size()); } } } @@ -60,11 +62,10 @@ public class PassRateUtil { /** * 计算 UI 成功的步骤数 * - * @param resultIdMap * @param stepList * @return */ - private static long getUISuccessSize(Map> resultIdMap, List stepList) { + private static long getUISuccessSize(List stepList) { AtomicLong atomicLong = new AtomicLong(); stepList.forEach(stepFather -> { stepFather.getChildren().forEach(step -> { @@ -72,17 +73,15 @@ public class PassRateUtil { if (CollectionUtils.isNotEmpty(step.getChildren())) { AtomicLong failCount = new AtomicLong(); AtomicLong unExecuteCount = new AtomicLong(); - getUIFailStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), failCount); - getUIUnExecuteStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), unExecuteCount); + getUIFailStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), failCount); + getUIUnExecuteStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), unExecuteCount); //复制或者嵌套场景的成功只算 1 次 if (failCount.get() == 0 && unExecuteCount.get() == 0) { atomicLong.getAndAdd(1); } } else { - if (resultIdMap.containsKey(step.getResourceId()) && CollectionUtils.isNotEmpty(resultIdMap.get(step.getResourceId()))) { - calculateCount(resultIdMap, atomicLong, step, ScenarioStatus.Success.name()); - } + calculateCount(atomicLong, step, ScenarioStatus.Success.name()); } }); }); @@ -94,44 +93,34 @@ public class PassRateUtil { * 递归叶子节点,有失败的证明嵌套的场景是失败的 * * @param stepTrees - * @param resultIdMap * @param count * @return */ - private static void getUIFailStepCount(Map> resultIdMap, List stepTrees, AtomicLong count) { + private static void getUIFailStepCount(List stepTrees, AtomicLong count) { stepTrees.forEach(step -> { if (CollectionUtils.isNotEmpty(step.getChildren())) { - getUIFailStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), count); + getUIFailStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), count); } else { - if (resultIdMap.containsKey(step.getResourceId()) && CollectionUtils.isNotEmpty(resultIdMap.get(step.getResourceId()))) { - calculateCount(resultIdMap, count, step, ScenarioStatus.Fail.name()); - } + calculateCount(count, step, ScenarioStatus.Fail.name()); } }); } - private static void getUIUnExecuteStepCount(Map> resultIdMap, List stepTrees, AtomicLong count) { + private static void getUIUnExecuteStepCount(List stepTrees, AtomicLong count) { stepTrees.forEach(step -> { if (CollectionUtils.isNotEmpty(step.getChildren())) { - getUIUnExecuteStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), count); + getUIUnExecuteStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), count); } else { - if (!resultIdMap.containsKey(step.getResourceId())) { + if (StringUtils.equalsIgnoreCase(step.getTotalStatus(), UNEXECUTE)) { count.getAndIncrement(); } } }); } - private static void calculateCount(Map> resultIdMap, AtomicLong failCount, StepTreeDTO step, String status) { - List sameResourceIdResults = resultIdMap.get(step.getResourceId()); - if (StringUtils.equalsIgnoreCase(sameResourceIdResults.get(0).getStatus(), status)) { - failCount.incrementAndGet(); - - //计算完结果移除 - sameResourceIdResults.remove(0); - if (CollectionUtils.isEmpty(sameResourceIdResults)) { - resultIdMap.remove(step.getResourceId()); - } + private static void calculateCount(AtomicLong count, StepTreeDTO step, String status) { + if (StringUtils.equalsIgnoreCase(status, step.getTotalStatus())) { + count.getAndIncrement(); } }