fix(UI 自动化): UI通过率计算完整修复

--bug=1016623 --user=张大海 【UI测试】当成功的步骤为0时-通过率计算错误 https://www.tapd.cn/55049933/s/1240952a
This commit is contained in:
zhangdahai112 2022-09-08 18:15:23 +08:00 committed by zhangdahai112
parent 3dade654bb
commit 573bcca512
2 changed files with 30 additions and 41 deletions

View File

@ -124,7 +124,7 @@ public class ApiScenarioReportService {
} else if (dto.getRunMode().startsWith("UI")) { } else if (dto.getRunMode().startsWith("UI")) {
ApiScenarioReportResultExample example = new ApiScenarioReportResultExample(); ApiScenarioReportResultExample example = new ApiScenarioReportResultExample();
example.createCriteria().andReportIdEqualTo(dto.getReportId()); example.createCriteria().andReportIdEqualTo(dto.getReportId());
scenarioReport = updateUiScenario(apiScenarioReportResultMapper.selectByExample(example), dto); scenarioReport = updateUiScenario(apiScenarioReportResultMapper.selectByExampleWithBLOBs(example), dto);
} else { } else {
scenarioReport = updateScenario(dto); scenarioReport = updateScenario(dto);
} }
@ -484,7 +484,7 @@ public class ApiScenarioReportService {
return report; return report;
} }
public ApiScenarioReport updateUiScenario(List<ApiScenarioReportResult> requestResults, ResultDTO dto) { public ApiScenarioReport updateUiScenario(List<ApiScenarioReportResultWithBLOBs> requestResults, ResultDTO dto) {
long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count(); long errorSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Error.name())).count();
// 更新报告状态 // 更新报告状态
String status = getStatus(dto); String status = getStatus(dto);
@ -525,7 +525,7 @@ public class ApiScenarioReportService {
} }
@Nullable @Nullable
private boolean updateUiScenario(List<ApiScenarioReportResult> requestResults, ResultDTO dto, long errorSize, String status, ApiScenarioReport report, UiScenarioWithBLOBs scenario) { private boolean updateUiScenario(List<ApiScenarioReportResultWithBLOBs> requestResults, ResultDTO dto, long errorSize, String status, ApiScenarioReport report, UiScenarioWithBLOBs scenario) {
if (StringUtils.equalsAnyIgnoreCase(status, ExecuteResult.UN_EXECUTE.toString())) { if (StringUtils.equalsAnyIgnoreCase(status, ExecuteResult.UN_EXECUTE.toString())) {
scenario.setLastResult(ScenarioStatus.Fail.name()); scenario.setLastResult(ScenarioStatus.Fail.name());
} else { } else {

View File

@ -3,10 +3,8 @@ package io.metersphere.api.service.utils;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import io.metersphere.api.dto.StepTreeDTO; import io.metersphere.api.dto.StepTreeDTO;
import io.metersphere.api.dto.automation.ScenarioStatus; import io.metersphere.api.dto.automation.ScenarioStatus;
import io.metersphere.base.domain.ApiScenarioReport; import io.metersphere.api.service.ApiScenarioReportStructureService;
import io.metersphere.base.domain.ApiScenarioReportResult; import io.metersphere.base.domain.*;
import io.metersphere.base.domain.ApiScenarioReportStructureExample;
import io.metersphere.base.domain.ApiScenarioReportStructureWithBLOBs;
import io.metersphere.base.mapper.ApiScenarioReportStructureMapper; import io.metersphere.base.mapper.ApiScenarioReportStructureMapper;
import io.metersphere.commons.utils.CommonBeanFactory; import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.constants.SystemConstants; import io.metersphere.constants.SystemConstants;
@ -28,31 +26,35 @@ import java.util.stream.Collectors;
*/ */
public class PassRateUtil { public class PassRateUtil {
public static String calculatePassRate(List<ApiScenarioReportResult> requestResults, ApiScenarioReport report) { private final static String ZERO_PERCENT = "0%";
public static final String UNEXECUTE = "unexecute";
public static String calculatePassRate(List<ApiScenarioReportResultWithBLOBs> requestResults, ApiScenarioReport report) {
if (CollectionUtils.isEmpty(requestResults)) { if (CollectionUtils.isEmpty(requestResults)) {
return "0"; return ZERO_PERCENT;
} else { } else {
long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count(); long successSize = requestResults.stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ScenarioStatus.Success.name())).count();
if (report.getReportType().startsWith(SystemConstants.TestTypeEnum.UI.name())) { if (report.getReportType().startsWith(SystemConstants.TestTypeEnum.UI.name())) {
//resourceId -> 结果列表 循环可能一个 resourceId 对应多个接口 //resourceId -> 结果列表 循环可能一个 resourceId 对应多个接口
Map<String, List<ApiScenarioReportResult>> resultResourceStatusMap = requestResults.stream().collect(Collectors.groupingBy(ApiScenarioReportResult::getResourceId)); Map<String, List<ApiScenarioReportResultWithBLOBs>> resultResourceStatusMap = requestResults.stream().collect(Collectors.groupingBy(ApiScenarioReportResult::getResourceId));
ApiScenarioReportStructureExample e = new ApiScenarioReportStructureExample(); ApiScenarioReportStructureExample e = new ApiScenarioReportStructureExample();
e.createCriteria().andReportIdEqualTo(report.getId()); e.createCriteria().andReportIdEqualTo(report.getId());
List<ApiScenarioReportStructureWithBLOBs> apiScenarioReportStructures = CommonBeanFactory.getBean(ApiScenarioReportStructureMapper.class).selectByExampleWithBLOBs(e); List<ApiScenarioReportStructureWithBLOBs> apiScenarioReportStructures = CommonBeanFactory.getBean(ApiScenarioReportStructureMapper.class).selectByExampleWithBLOBs(e);
if (CollectionUtils.isEmpty(apiScenarioReportStructures)) { if (CollectionUtils.isEmpty(apiScenarioReportStructures)) {
return "0"; return ZERO_PERCENT;
} }
List<StepTreeDTO> stepList = JSONArray.parseArray(new String(apiScenarioReportStructures.get(0).getResourceTree(), StandardCharsets.UTF_8), StepTreeDTO.class); List<StepTreeDTO> 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)) { 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 { } 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 成功的步骤数 * 计算 UI 成功的步骤数
* *
* @param resultIdMap
* @param stepList * @param stepList
* @return * @return
*/ */
private static long getUISuccessSize(Map<String, List<ApiScenarioReportResult>> resultIdMap, List<StepTreeDTO> stepList) { private static long getUISuccessSize(List<StepTreeDTO> stepList) {
AtomicLong atomicLong = new AtomicLong(); AtomicLong atomicLong = new AtomicLong();
stepList.forEach(stepFather -> { stepList.forEach(stepFather -> {
stepFather.getChildren().forEach(step -> { stepFather.getChildren().forEach(step -> {
@ -72,17 +73,15 @@ public class PassRateUtil {
if (CollectionUtils.isNotEmpty(step.getChildren())) { if (CollectionUtils.isNotEmpty(step.getChildren())) {
AtomicLong failCount = new AtomicLong(); AtomicLong failCount = new AtomicLong();
AtomicLong unExecuteCount = new AtomicLong(); AtomicLong unExecuteCount = new AtomicLong();
getUIFailStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), failCount); getUIFailStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), failCount);
getUIUnExecuteStepCount(resultIdMap, Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), unExecuteCount); getUIUnExecuteStepCount(Optional.ofNullable(step.getChildren()).orElse(new ArrayList<>()), unExecuteCount);
//复制或者嵌套场景的成功只算 1 //复制或者嵌套场景的成功只算 1
if (failCount.get() == 0 && unExecuteCount.get() == 0) { if (failCount.get() == 0 && unExecuteCount.get() == 0) {
atomicLong.getAndAdd(1); atomicLong.getAndAdd(1);
} }
} else { } else {
if (resultIdMap.containsKey(step.getResourceId()) && CollectionUtils.isNotEmpty(resultIdMap.get(step.getResourceId()))) { calculateCount(atomicLong, step, ScenarioStatus.Success.name());
calculateCount(resultIdMap, atomicLong, step, ScenarioStatus.Success.name());
}
} }
}); });
}); });
@ -94,44 +93,34 @@ public class PassRateUtil {
* 递归叶子节点有失败的证明嵌套的场景是失败的 * 递归叶子节点有失败的证明嵌套的场景是失败的
* *
* @param stepTrees * @param stepTrees
* @param resultIdMap
* @param count * @param count
* @return * @return
*/ */
private static void getUIFailStepCount(Map<String, List<ApiScenarioReportResult>> resultIdMap, List<StepTreeDTO> stepTrees, AtomicLong count) { private static void getUIFailStepCount(List<StepTreeDTO> stepTrees, AtomicLong count) {
stepTrees.forEach(step -> { stepTrees.forEach(step -> {
if (CollectionUtils.isNotEmpty(step.getChildren())) { 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 { } else {
if (resultIdMap.containsKey(step.getResourceId()) && CollectionUtils.isNotEmpty(resultIdMap.get(step.getResourceId()))) { calculateCount(count, step, ScenarioStatus.Fail.name());
calculateCount(resultIdMap, count, step, ScenarioStatus.Fail.name());
}
} }
}); });
} }
private static void getUIUnExecuteStepCount(Map<String, List<ApiScenarioReportResult>> resultIdMap, List<StepTreeDTO> stepTrees, AtomicLong count) { private static void getUIUnExecuteStepCount(List<StepTreeDTO> stepTrees, AtomicLong count) {
stepTrees.forEach(step -> { stepTrees.forEach(step -> {
if (CollectionUtils.isNotEmpty(step.getChildren())) { 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 { } else {
if (!resultIdMap.containsKey(step.getResourceId())) { if (StringUtils.equalsIgnoreCase(step.getTotalStatus(), UNEXECUTE)) {
count.getAndIncrement(); count.getAndIncrement();
} }
} }
}); });
} }
private static void calculateCount(Map<String, List<ApiScenarioReportResult>> resultIdMap, AtomicLong failCount, StepTreeDTO step, String status) { private static void calculateCount(AtomicLong count, StepTreeDTO step, String status) {
List<ApiScenarioReportResult> sameResourceIdResults = resultIdMap.get(step.getResourceId()); if (StringUtils.equalsIgnoreCase(status, step.getTotalStatus())) {
if (StringUtils.equalsIgnoreCase(sameResourceIdResults.get(0).getStatus(), status)) { count.getAndIncrement();
failCount.incrementAndGet();
//计算完结果移除
sameResourceIdResults.remove(0);
if (CollectionUtils.isEmpty(sameResourceIdResults)) {
resultIdMap.remove(step.getResourceId());
}
} }
} }