fix(接口测试): 修复执行场景,通过率不更新的缺陷

--bug=1019460 --user=王孝刚 【接口测试】测试计划-场景用例-通过率显示NAN
https://www.tapd.cn/55049933/s/1291157
This commit is contained in:
wxg0103 2022-11-07 18:56:55 +08:00 committed by wxg0103
parent 502aa1c588
commit 5225fa52bd
4 changed files with 69 additions and 42 deletions

View File

@ -9,6 +9,7 @@ import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.FileUtils; import io.metersphere.commons.utils.FileUtils;
import io.metersphere.commons.utils.FixedCapacityUtil; import io.metersphere.commons.utils.FixedCapacityUtil;
import io.metersphere.commons.utils.JSON; import io.metersphere.commons.utils.JSON;
import io.metersphere.commons.vo.ResultVO;
import io.metersphere.constants.BackendListenerConstants; import io.metersphere.constants.BackendListenerConstants;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
@ -35,7 +36,7 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
private List<SampleResult> queues; private List<SampleResult> queues;
private ResultDTO dto; private ResultDTO dto;
// 当前场景报告/用例结果状态 // 当前场景报告/用例结果状态
private String status; private ResultVO resultVO;
/** /**
* 参数初始化方法 * 参数初始化方法
@ -51,6 +52,7 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
if (testResultService == null) { if (testResultService == null) {
testResultService = CommonBeanFactory.getBean(TestResultService.class); testResultService = CommonBeanFactory.getBean(TestResultService.class);
} }
resultVO = new ResultVO();
super.setupTest(context); super.setupTest(context);
} }
@ -67,8 +69,8 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
JMeterBase.resultFormatting(sampleResults, dto); JMeterBase.resultFormatting(sampleResults, dto);
testResultService.saveResults(dto); testResultService.saveResults(dto);
status = ReportStatusUtil.getStatus(dto, status); resultVO = ReportStatusUtil.getStatus(dto, resultVO);
dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, status); dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, resultVO);
sampleResults.clear(); sampleResults.clear();
} }
} }
@ -93,8 +95,8 @@ public class MsApiBackendListener extends AbstractBackendListenerClient implemen
LoggerUtil.info("执行结果入库存储", dto.getReportId()); LoggerUtil.info("执行结果入库存储", dto.getReportId());
testResultService.saveResults(dto); testResultService.saveResults(dto);
status = ReportStatusUtil.getStatus(dto, status); resultVO = ReportStatusUtil.getStatus(dto, resultVO);
dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, status); dto.getArbitraryData().put(CommonConstants.LOCAL_STATUS_KEY, resultVO);
LoggerUtil.info("重试结果处理结束", dto.getReportId()); LoggerUtil.info("重试结果处理结束", dto.getReportId());
} }
// 全局并发队列 // 全局并发队列

View File

@ -2,6 +2,7 @@ package io.metersphere.api.jmeter.utils;
import io.metersphere.commons.constants.CommonConstants; import io.metersphere.commons.constants.CommonConstants;
import io.metersphere.commons.enums.ApiReportStatus; import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.vo.ResultVO;
import io.metersphere.dto.RequestResult; import io.metersphere.dto.RequestResult;
import io.metersphere.dto.ResultDTO; import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil; import io.metersphere.utils.LoggerUtil;
@ -42,25 +43,27 @@ public class ReportStatusUtil {
* @param dto jmeter返回 * @param dto jmeter返回
* @return * @return
*/ */
public static String getStatus(ResultDTO dto, String status) { public static ResultVO getStatus(ResultDTO dto, ResultVO resultVO) {
if (StringUtils.equals(status, ApiReportStatus.ERROR.name())) { resultVO.computerTotal(dto.getRequestResults().size());
return status; resultVO.computerSuccess(dto.getRequestResults().stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.SUCCESS.name())).count());
if (StringUtils.equals(resultVO.getStatus(), ApiReportStatus.ERROR.name())) {
return resultVO;
} }
if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.REPORT_STATUS)) { if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.REPORT_STATUS)) {
// 资源池执行整体传输失败单条传输内容获取资源池执行统计的状态 // 资源池执行整体传输失败单条传输内容获取资源池执行统计的状态
return String.valueOf(dto.getArbitraryData().get(CommonConstants.REPORT_STATUS)); resultVO.setStatus(String.valueOf(dto.getArbitraryData().get(CommonConstants.REPORT_STATUS)));
} }
// 过滤掉重试结果后进行统计 // 过滤掉重试结果后进行统计
List<RequestResult> requestResults = filterRetryResults(dto.getRequestResults()); List<RequestResult> requestResults = filterRetryResults(dto.getRequestResults());
long errorSize = requestResults.stream().filter(requestResult -> long errorSize = requestResults.stream().filter(requestResult ->
StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.ERROR.name())).count(); StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.ERROR.name())).count();
// 误报 // 误报
long errorReportResultSize = dto.getRequestResults().stream(). filter( long errorReportResultSize = dto.getRequestResults().stream().filter(
requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.FAKE_ERROR.name())).count(); requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.FAKE_ERROR.name())).count();
// 默认状态 // 默认状态
status = dto.getRequestResults().isEmpty() && StringUtils.isEmpty(status) String status = dto.getRequestResults().isEmpty() && StringUtils.isEmpty(resultVO.getStatus())
? ApiReportStatus.PENDING.name() ? ApiReportStatus.PENDING.name()
: StringUtils.defaultIfEmpty(status, ApiReportStatus.SUCCESS.name()); : StringUtils.defaultIfEmpty(resultVO.getStatus(), ApiReportStatus.SUCCESS.name());
if (errorSize > 0) { if (errorSize > 0) {
status = ApiReportStatus.ERROR.name(); status = ApiReportStatus.ERROR.name();
} else if (errorReportResultSize > 0) { } else if (errorReportResultSize > 0) {
@ -73,18 +76,22 @@ public class ReportStatusUtil {
LoggerUtil.info("资源 " + dto.getTestId() + " 执行超时", dto.getReportId()); LoggerUtil.info("资源 " + dto.getTestId() + " 执行超时", dto.getReportId());
status = ApiReportStatus.ERROR.name(); status = ApiReportStatus.ERROR.name();
} }
return status; resultVO.setStatus(status);
return resultVO;
} }
public static String getStatus(ResultDTO dto) { public static ResultVO computedProcess(ResultDTO dto) {
ResultVO result = new ResultVO();
if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.LOCAL_STATUS_KEY)) { if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.LOCAL_STATUS_KEY)) {
// 本地执行状态 // 本地执行状态
return String.valueOf(dto.getArbitraryData().get(CommonConstants.LOCAL_STATUS_KEY)); result = (ResultVO) dto.getArbitraryData().get(CommonConstants.LOCAL_STATUS_KEY);
return result;
} }
if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.REPORT_STATUS)) { if (MapUtils.isNotEmpty(dto.getArbitraryData()) && dto.getArbitraryData().containsKey(CommonConstants.REPORT_STATUS)) {
// 资源池执行整体传输失败单条传输内容获取资源池执行统计的状态 // 资源池执行整体传输失败单条传输内容获取资源池执行统计的状态
return String.valueOf(dto.getArbitraryData().get(CommonConstants.REPORT_STATUS)); result = (ResultVO) dto.getArbitraryData().get(CommonConstants.REPORT_STATUS);
return result;
} }
return getStatus(dto, ""); return getStatus(dto, result);
} }
} }

View File

@ -0,0 +1,27 @@
package io.metersphere.commons.vo;
import lombok.Data;
import java.text.DecimalFormat;
@Data
public class ResultVO {
private String status;
private long scenarioSuccess;
private int scenarioTotal;
public void computerTotal(int total) {
this.scenarioTotal += total;
}
public void computerSuccess(long success) {
this.scenarioSuccess += success;
}
public String computerPassRate() {
return new DecimalFormat("0%").format((float) this.scenarioSuccess / this.scenarioTotal);
}
}

View File

@ -18,6 +18,7 @@ import io.metersphere.commons.constants.*;
import io.metersphere.commons.enums.ApiReportStatus; import io.metersphere.commons.enums.ApiReportStatus;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.*; import io.metersphere.commons.utils.*;
import io.metersphere.commons.vo.ResultVO;
import io.metersphere.constants.RunModeConstants; import io.metersphere.constants.RunModeConstants;
import io.metersphere.dto.*; import io.metersphere.dto.*;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
@ -41,7 +42,6 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -278,20 +278,17 @@ public class ApiScenarioReportService {
} }
public ApiScenarioReport updatePlanCase(ResultDTO dto) { public ApiScenarioReport updatePlanCase(ResultDTO dto) {
String status = ReportStatusUtil.getStatus(dto); ResultVO resultVO = ReportStatusUtil.computedProcess(dto);
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), resultVO.getStatus(), dto.getRunMode());
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId()); TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId());
if (testPlanApiScenario != null) { if (testPlanApiScenario != null) {
if (report != null) { if (report != null) {
testPlanApiScenario.setLastResult(report.getStatus()); testPlanApiScenario.setLastResult(report.getStatus());
report.setScenarioId(testPlanApiScenario.getApiScenarioId()); report.setScenarioId(testPlanApiScenario.getApiScenarioId());
} else { } else {
testPlanApiScenario.setLastResult(status); testPlanApiScenario.setLastResult(resultVO.getStatus());
} }
long successSize = dto.getRequestResults().stream().filter(requestResult -> String passRate = resultVO.computerPassRate();
StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.SUCCESS.name())).count();
String passRate = new DecimalFormat("0%").format((float) successSize / dto.getRequestResults().size());
testPlanApiScenario.setPassRate(passRate); testPlanApiScenario.setPassRate(passRate);
testPlanApiScenario.setReportId(dto.getReportId()); testPlanApiScenario.setReportId(dto.getReportId());
testPlanApiScenario.setUpdateTime(System.currentTimeMillis()); testPlanApiScenario.setUpdateTime(System.currentTimeMillis());
@ -300,7 +297,7 @@ public class ApiScenarioReportService {
// 更新场景状态 // 更新场景状态
ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId()); ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
if (scenario != null) { if (scenario != null) {
scenario.setLastResult(status); scenario.setLastResult(resultVO.getStatus());
scenario.setPassRate(passRate); scenario.setPassRate(passRate);
scenario.setReportId(dto.getReportId()); scenario.setReportId(dto.getReportId());
int executeTimes = 0; int executeTimes = 0;
@ -317,8 +314,8 @@ public class ApiScenarioReportService {
public ApiScenarioReport updateSchedulePlanCase(ResultDTO dto) { public ApiScenarioReport updateSchedulePlanCase(ResultDTO dto) {
List<String> testPlanReportIdList = new ArrayList<>(); List<String> testPlanReportIdList = new ArrayList<>();
String status = ReportStatusUtil.getStatus(dto); ResultVO resultVO = ReportStatusUtil.computedProcess(dto);
ApiScenarioReportWithBLOBs report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReportWithBLOBs report = editReport(dto.getReportType(), dto.getReportId(), resultVO.getStatus(), dto.getRunMode());
if (report != null) { if (report != null) {
if (StringUtils.isNotEmpty(dto.getTestPlanReportId()) && !testPlanReportIdList.contains(dto.getTestPlanReportId())) { if (StringUtils.isNotEmpty(dto.getTestPlanReportId()) && !testPlanReportIdList.contains(dto.getTestPlanReportId())) {
testPlanReportIdList.add(dto.getTestPlanReportId()); testPlanReportIdList.add(dto.getTestPlanReportId());
@ -326,9 +323,8 @@ public class ApiScenarioReportService {
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId()); TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(dto.getTestId());
if (testPlanApiScenario != null) { if (testPlanApiScenario != null) {
testPlanApiScenario.setLastResult(report.getStatus()); testPlanApiScenario.setLastResult(report.getStatus());
long successSize = dto.getRequestResults().stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.SUCCESS.name())).count(); String passRate = resultVO.computerPassRate();
String passRate = new DecimalFormat("0%").format((float) successSize / dto.getRequestResults().size()); testPlanApiScenario.setPassRate(resultVO.computerPassRate());
testPlanApiScenario.setPassRate(passRate);
testPlanApiScenario.setReportId(report.getId()); testPlanApiScenario.setReportId(report.getId());
testPlanApiScenario.setUpdateTime(System.currentTimeMillis()); testPlanApiScenario.setUpdateTime(System.currentTimeMillis());
@ -337,7 +333,7 @@ public class ApiScenarioReportService {
// 更新场景状态 // 更新场景状态
ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId()); ApiScenario scenario = apiScenarioMapper.selectByPrimaryKey(testPlanApiScenario.getApiScenarioId());
if (scenario != null) { if (scenario != null) {
scenario.setLastResult(status); scenario.setLastResult(resultVO.getStatus());
scenario.setPassRate(passRate); scenario.setPassRate(passRate);
scenario.setReportId(report.getId()); scenario.setReportId(report.getId());
int executeTimes = 0; int executeTimes = 0;
@ -420,22 +416,17 @@ public class ApiScenarioReportService {
public ApiScenarioReport updateScenario(ResultDTO dto) { public ApiScenarioReport updateScenario(ResultDTO dto) {
// 更新报告状态 // 更新报告状态
String status = ReportStatusUtil.getStatus(dto); ResultVO resultVO = ReportStatusUtil.computedProcess(dto);
ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), status, dto.getRunMode()); ApiScenarioReport report = editReport(dto.getReportType(), dto.getReportId(), resultVO.getStatus(), dto.getRunMode());
// 更新场景状态 // 更新场景状态
ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(dto.getTestId()); ApiScenarioWithBLOBs scenario = apiScenarioMapper.selectByPrimaryKey(dto.getTestId());
if (scenario == null) { if (scenario == null) {
scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId()); scenario = apiScenarioMapper.selectByPrimaryKey(report.getScenarioId());
} }
if (scenario != null) { if (scenario != null) {
scenario.setLastResult(status); scenario.setLastResult(resultVO.getStatus());
long successSize = dto.getRequestResults().stream().filter(requestResult -> StringUtils.equalsIgnoreCase(requestResult.getStatus(), ApiReportStatus.SUCCESS.name())).count(); scenario.setPassRate(resultVO.computerPassRate());
if (dto.getRequestResults().size() == 0) { scenario.setPassRate(resultVO.computerPassRate());
scenario.setPassRate("0%");
} else {
scenario.setPassRate(new DecimalFormat("0%").format((float) successSize / dto.getRequestResults().size()));
}
scenario.setReportId(dto.getReportId()); scenario.setReportId(dto.getReportId());
int executeTimes = 0; int executeTimes = 0;
if (scenario.getExecuteTimes() != null) { if (scenario.getExecuteTimes() != null) {