refactor(接口测试): 优化场景报告的存储以及加载方式

--story=1006590 --user=宋天阳 【性能优化】【接口测试报告,调试报告】调试报告,接口测试报告,都应该改成懒加载,
初始页面是 请求列表信息,不加载 任何日志。只有当用户 下探到 某一个 特定请求后,才加载 这个请求对应的日志。
https://www.tapd.cn/55049933/s/1130302
This commit is contained in:
song-tianyang 2022-04-08 11:42:51 +08:00 committed by CountryBuilder
parent f343fa6043
commit d3da8d9a0e
16 changed files with 718 additions and 39 deletions

View File

@ -14,6 +14,7 @@ import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.OperLogModule;
import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.dto.RequestResult;
import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.notice.annotation.SendNotice;
import org.springframework.web.bind.annotation.*;
@ -46,6 +47,11 @@ public class APIScenarioReportController {
return apiReportService.update(node);
}
@GetMapping("/selectReportContent/{stepId}")
public RequestResult selectReportContent(@PathVariable String stepId) {
return apiReportService.selectReportContent(stepId);
}
@PostMapping("/delete")
@MsAuditLog(module = OperLogModule.API_AUTOMATION_REPORT, type = OperLogConstants.DELETE, beforeEvent = "#msClass.getLogDetails(#request.id)", msClass = ApiScenarioReportService.class)
@SendNotice(taskType = NoticeConstants.TaskType.API_REPORT_TASK, event = NoticeConstants.Event.DELETE, target = "#targetClass.get(#request.id)", targetClass = ApiScenarioReportService.class,

View File

@ -1,6 +1,8 @@
package io.metersphere.api.dto;
import io.metersphere.base.domain.ApiScenarioReportResult;
import io.metersphere.dto.RequestResult;
import io.metersphere.dto.ResponseResult;
import lombok.Getter;
import lombok.Setter;
@ -10,5 +12,19 @@ import java.util.Map;
@Setter
public class RequestResultExpandDTO extends RequestResult {
private String status;
private Map<String,String> attachInfoMap;
private Map<String, String> attachInfoMap;
public RequestResultExpandDTO() {
}
public RequestResultExpandDTO(ApiScenarioReportResult requestResult) {
this.setName(requestResult.getReqName());
this.setSuccess(requestResult.getReqSuccess());
this.setError(requestResult.getReqError());
this.setStartTime(requestResult.getReqStartTime());
ResponseResult responseResult = this.getResponseResult();
responseResult.setResponseCode(requestResult.getRspCode());
responseResult.setResponseTime(requestResult.getRspTime());
this.setResponseResult(responseResult);
}
}

View File

@ -15,6 +15,7 @@ public class StepTreeDTO {
private String label;
private RequestResult value;
private String allIndex;
private String stepId;
//误报库编码
private String errorCode;
@ -30,11 +31,12 @@ public class StepTreeDTO {
}
public StepTreeDTO(String name, String resourceId, String type, int index) {
public StepTreeDTO(String name, String resourceId, String type, String stepId, int index) {
this.label = StringUtils.isNotEmpty(name) ? name : type;
this.resourceId = resourceId;
this.type = type;
this.index = index;
this.stepId = stepId;
this.children = new LinkedList<>();
}
}

View File

@ -7,6 +7,7 @@ import io.metersphere.base.domain.ApiScenarioReportResult;
import io.metersphere.base.mapper.ApiScenarioReportResultMapper;
import io.metersphere.commons.constants.ExecuteResult;
import io.metersphere.commons.utils.ErrorReportLibraryUtil;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.dto.RequestResult;
import io.metersphere.dto.ResultDTO;
import io.metersphere.utils.LoggerUtil;
@ -120,7 +121,58 @@ public class ApiScenarioReportResultService {
}
report.setStatus(status);
report.setRequestTime(result.getEndTime() - result.getStartTime());
//记录基础信息
report.setReqName(StringUtils.isEmpty(result.getName()) ? "" : result.getName());
report.setReqSuccess(result.isSuccess());
report.setReqError(result.getError());
report.setReqStartTime(result.getStartTime());
if (result.getResponseResult() != null) {
report.setRspCode(result.getResponseResult().getResponseCode());
report.setRspTime(result.getResponseResult().getResponseTime());
} else {
report.setRspCode("");
report.setRspTime(Long.valueOf(0));
}
report.setContent(JSON.toJSONString(result).getBytes(StandardCharsets.UTF_8));
return report;
}
public boolean isResultFormat(ApiScenarioReportResult result) {
if (result != null) {
if (result.getReqName() == null && result.getReqStartTime() == null && result.getRspCode() == null && result.getRspTime() == null) {
return false;
}
}
return true;
}
public ApiScenarioReportResult formatScenarioResult(ApiScenarioReportResult result) {
if (!this.isResultFormat(result)) {
ApiScenarioReportResult baseResult = apiScenarioReportResultMapper.selectByPrimaryKey(result.getId());
if (baseResult != null) {
try {
RequestResult requestResult = JSON.parseObject(new String(baseResult.getContent(), StandardCharsets.UTF_8), RequestResult.class);
//记录基础信息
baseResult.setReqName(StringUtils.isEmpty(requestResult.getName()) ? "" : requestResult.getName());
baseResult.setReqSuccess(requestResult.isSuccess());
baseResult.setReqError(requestResult.getError());
baseResult.setReqStartTime(requestResult.getStartTime());
if (requestResult.getResponseResult() != null) {
baseResult.setRspCode(requestResult.getResponseResult().getResponseCode());
baseResult.setRspTime(requestResult.getResponseResult().getResponseTime());
} else {
baseResult.setRspCode("");
baseResult.setRspTime(Long.valueOf(0));
}
apiScenarioReportResultMapper.updateByPrimaryKeySelective(baseResult);
return baseResult;
} catch (Exception e) {
LogUtil.error("format scenario result error:" + e.getMessage());
}
}
}
return result;
}
}

View File

@ -912,4 +912,8 @@ public class ApiScenarioReportService {
}
}
}
public RequestResult selectReportContent(String stepId) {
return apiScenarioReportStructureService.selectReportContent(stepId);
}
}

View File

@ -9,6 +9,8 @@ import io.metersphere.api.dto.StepTreeDTO;
import io.metersphere.api.service.vo.ApiDefinitionExecResultVo;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtApiScenarioReportResultMapper;
import io.metersphere.commons.constants.ExecuteResult;
import io.metersphere.commons.constants.MsTestElementConstants;
import io.metersphere.commons.constants.ReportTypeConstants;
import io.metersphere.commons.utils.BeanUtils;
@ -41,9 +43,13 @@ public class ApiScenarioReportStructureService {
private ApiScenarioReportMapper scenarioReportMapper;
@Resource
private ApiDefinitionExecResultMapper definitionExecResultMapper;
@Resource
private ApiScenarioReportResultService apiScenarioReportResultService;
@Resource
private ExtApiScenarioReportResultMapper extApiScenarioReportResultMapper;
private static final List<String> requests = Arrays.asList("HTTPSamplerProxy", "DubboSampler", "JDBCSampler", "TCPSampler", "JSR223Processor", "AbstractSampler", "MsUiCommand");
private static final List<String> controls = Arrays.asList("Assertions","IfController","ConstantTimer");
private static final List<String> controls = Arrays.asList("Assertions", "IfController", "ConstantTimer");
public void save(List<ApiScenarioWithBLOBs> apiScenarios, String reportId, String reportType) {
List<StepTreeDTO> dtoList = new LinkedList<>();
@ -123,7 +129,7 @@ public class ApiScenarioReportStructureService {
resourceId = id + "=" + resourceId;
}
}
dto = new StepTreeDTO(name, resourceId, element.getString("type"), 1);
dto = new StepTreeDTO(name, resourceId, element.getString("type"), resourceId, 1);
dto.setAllIndex(null);
if (element.containsKey("hashTree") && !requests.contains(dto.getType())) {
JSONArray elementJSONArray = element.getJSONArray("hashTree");
@ -158,7 +164,7 @@ public class ApiScenarioReportStructureService {
resourceId = id + "=" + resourceId;
}
}
StepTreeDTO children = new StepTreeDTO(element.getString("name"), resourceId, element.getString("type"), element.getIntValue("index"));
StepTreeDTO children = new StepTreeDTO(element.getString("name"), resourceId, element.getString("type"), resourceId, element.getIntValue("index"));
if (StringUtils.isNotBlank(children.getType()) && children.getType().equals("MsUiCommand")) {
children.setResourceId(resourceId);
children.setLabel(element.getString("command"));
@ -186,7 +192,7 @@ public class ApiScenarioReportStructureService {
for (StepTreeDTO step : dtoList) {
if (step.getValue() != null) {
if (step.getValue() instanceof RequestResultExpandDTO
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), "unexecute")) {
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), ExecuteResult.unexecute.name())) {
isUnExecute.set(isUnExecute.longValue() + 1);
} else if (StringUtils.isNotEmpty(step.getErrorCode())) {
isErrorReport.set(isErrorReport.longValue() + 1);
@ -268,7 +274,7 @@ public class ApiScenarioReportStructureService {
}
}
public static void reportFormatting(List<StepTreeDTO> dtoList, Map<String, List<ApiScenarioReportResult>> maps) {
public void reportFormatting(List<StepTreeDTO> dtoList, Map<String, List<ApiScenarioReportResult>> maps) {
for (int index = 0; index < dtoList.size(); index++) {
StepTreeDTO dto = dtoList.get(index);
dto.setIndex((index + 1));
@ -276,19 +282,27 @@ public class ApiScenarioReportStructureService {
if (CollectionUtils.isNotEmpty(reportResults)) {
if (reportResults.size() > 1) {
for (int i = 0; i < reportResults.size(); i++) {
ApiScenarioReportResult reportResult = reportResults.get(i);
reportResult = apiScenarioReportResultService.formatScenarioResult(reportResult);
if (i == 0) {
dto.setValue(JSON.parseObject(new String(reportResults.get(i).getContent(), StandardCharsets.UTF_8), RequestResult.class));
RequestResultExpandDTO requestResultExpandDTO = new RequestResultExpandDTO(reportResult);
dto.setStepId(reportResults.get(i).getId());
dto.setValue(requestResultExpandDTO);
dto.setErrorCode(reportResults.get(0).getErrorCode());
} else {
StepTreeDTO step = new StepTreeDTO(dto.getLabel(), UUID.randomUUID().toString(), dto.getType(), (i + 1));
step.setValue(JSON.parseObject(new String(reportResults.get(i).getContent(), StandardCharsets.UTF_8), RequestResult.class));
StepTreeDTO step = new StepTreeDTO(dto.getLabel(), UUID.randomUUID().toString(), dto.getType(), reportResults.get(i).getId(), (i + 1));
RequestResultExpandDTO requestResultExpandDTO = new RequestResultExpandDTO(reportResult);
step.setValue(requestResultExpandDTO);
step.setErrorCode(reportResults.get(i).getErrorCode());
dtoList.add(step);
}
}
} else {
String content = new String(reportResults.get(0).getContent(), StandardCharsets.UTF_8);
dto.setValue(JSON.parseObject(content, RequestResult.class));
ApiScenarioReportResult reportResult = reportResults.get(0);
reportResult = apiScenarioReportResultService.formatScenarioResult(reportResult);
RequestResultExpandDTO requestResultExpandDTO = new RequestResultExpandDTO(reportResult);
dto.setStepId(reportResults.get(0).getId());
dto.setValue(requestResultExpandDTO);
dto.setErrorCode(reportResults.get(0).getErrorCode());
}
}
@ -350,7 +364,7 @@ public class ApiScenarioReportStructureService {
//当有多个子步骤结果时如果当前步骤不是场景失败>误报>未执行>成功>未执行 如果是场景误报>失败>成功>未执行
if (failCount == 0 && errorReportCount == 0 && successCount == 0) {
dto.setTotalStatus("unexecute");
dto.setTotalStatus(ExecuteResult.unexecute.name());
} else if (successCount == dto.getChildren().size() || (successCount > 0 && errorReportCount == 0 && failCount == 0)) {
dto.setTotalStatus("success");
} else {
@ -372,17 +386,16 @@ public class ApiScenarioReportStructureService {
}
}
}
}
if (StringUtils.isEmpty(dto.getTotalStatus())) {
dto.setTotalStatus("unexecute");
dto.setTotalStatus(ExecuteResult.unexecute.name());
}
}
// 循环步骤请求从新排序
try {
if (dtoList.stream().filter(e -> e.getValue() != null).collect(Collectors.toList()).size() == dtoList.size()) {
List<StepTreeDTO> unList = dtoList.stream().filter(e -> e.getValue() != null
&& StringUtils.equalsIgnoreCase(e.getTotalStatus(), "unexecute")).collect(Collectors.toList());
&& StringUtils.equalsIgnoreCase(e.getTotalStatus(), ExecuteResult.unexecute.name())).collect(Collectors.toList());
List<StepTreeDTO> list = dtoList.stream().filter(e -> e.getValue().getStartTime() != 0).collect(Collectors.toList());
list = list.stream().sorted(Comparator.comparing(x -> x.getValue().getStartTime())).collect(Collectors.toList());
unList = unList.stream().sorted(Comparator.comparing(x -> x.getIndex())).collect(Collectors.toList());
@ -429,12 +442,12 @@ public class ApiScenarioReportStructureService {
}
if (vo.getRequestResult() == null) {
RequestResultExpandDTO requestResultExpandDTO = new RequestResultExpandDTO();
requestResultExpandDTO.setStatus("unexecute");
requestResultExpandDTO.setStatus(ExecuteResult.unexecute.name());
requestResultExpandDTO.setName(item.getName());
vo.setRequestResult(requestResultExpandDTO);
}
StepTreeDTO treeDTO = new StepTreeDTO(item.getName(), item.getResourceId(), "API", (i + 1));
treeDTO.setValue(vo.getRequestResult());
StepTreeDTO treeDTO = new StepTreeDTO(item.getName(), item.getResourceId(), "API", item.getId(), (i + 1));
// treeDTO.setValue(vo.getRequestResult());
if (vo.getRequestResult() != null && vo.getRequestResult() instanceof RequestResultExpandDTO) {
RequestResultExpandDTO expandDTO = (RequestResultExpandDTO) vo.getRequestResult();
if (expandDTO.getAttachInfoMap() != null && expandDTO.getAttachInfoMap().get("errorReportResult") != null) {
@ -467,7 +480,7 @@ public class ApiScenarioReportStructureService {
if (CollectionUtils.isNotEmpty(reportResults)) {
reportDTO.setTotal(reportResults.size());
reportDTO.setError(reportResults.stream().filter(e -> StringUtils.equalsAnyIgnoreCase(e.getStatus(), "Error")).collect(Collectors.toList()).size());
reportDTO.setUnExecute(reportResults.stream().filter(e -> StringUtils.equalsAnyIgnoreCase(e.getStatus(), "STOP", "unexecute")).collect(Collectors.toList()).size());
reportDTO.setUnExecute(reportResults.stream().filter(e -> StringUtils.equalsAnyIgnoreCase(e.getStatus(), "STOP", ExecuteResult.unexecute.name())).collect(Collectors.toList()).size());
reportDTO.setErrorCode(reportResults.stream().filter(e -> StringUtils.equalsAnyIgnoreCase(e.getStatus(), "errorReportResult")).collect(Collectors.toList()).size());
reportDTO.setPassAssertions(reportResults.stream().mapToLong(ApiDefinitionExecResultVo::getPassAssertions).sum());
reportDTO.setTotalAssertions(reportResults.stream().mapToLong(ApiDefinitionExecResultVo::getTotalAssertions).sum());
@ -503,11 +516,16 @@ public class ApiScenarioReportStructureService {
}
private ApiScenarioReportDTO getReport(String reportId) {
List<ApiScenarioReportResult> reportResults = null;
ApiScenarioReport report = scenarioReportMapper.selectByPrimaryKey(reportId);
if (report.getReportType() != null && report.getReportType().startsWith("UI")) {
ApiScenarioReportResultExample example = new ApiScenarioReportResultExample();
example.createCriteria().andReportIdEqualTo(reportId);
List<ApiScenarioReportResult> reportResults = reportResultMapper.selectByExampleWithBLOBs(example);
removeUiResultIfNotStep(reportResults, reportId);
reportResults = reportResultMapper.selectByExampleWithBLOBs(example);
removeUiResultIfNotStep(reportResults);
}else {
reportResults = this.selectBaseInfoResultByReportId(reportId);
}
ApiScenarioReportStructureExample structureExample = new ApiScenarioReportStructureExample();
structureExample.createCriteria().andReportIdEqualTo(reportId);
@ -555,14 +573,17 @@ public class ApiScenarioReportStructureService {
return reportDTO;
}
private List<ApiScenarioReportResult> selectBaseInfoResultByReportId(String reportId) {
return extApiScenarioReportResultMapper.selectBaseInfoResultByReportId(reportId);
}
/**
* UI 测试结果统计去掉前后置或其他不算步骤的执行结果
*
* @param reportResults
* @param reportId
*/
private void removeUiResultIfNotStep(List<ApiScenarioReportResult> reportResults, String reportId) {
ApiScenarioReport report = scenarioReportMapper.selectByPrimaryKey(reportId);
if (report.getReportType() != null && report.getReportType().startsWith("UI")) {
private void removeUiResultIfNotStep(List<ApiScenarioReportResult> reportResults) {
if(CollectionUtils.isNotEmpty(reportResults)){
Iterator<ApiScenarioReportResult> iterator = reportResults.iterator();
while (iterator.hasNext()) {
ApiScenarioReportResult item = iterator.next();
@ -581,7 +602,7 @@ public class ApiScenarioReportStructureService {
for (StepTreeDTO step : stepList) {
if (step.getValue() != null) {
if (step.getValue() instanceof RequestResultExpandDTO
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), "unexecute")) {
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), ExecuteResult.unexecute.name())) {
allUnExecute.set(allUnExecute.longValue() + 1);
}
}
@ -610,12 +631,11 @@ public class ApiScenarioReportStructureService {
return reportDTO;
}
private void stepChildrenErrorCalculate(List<StepTreeDTO> dtoList, AtomicLong isError, AtomicLong isErrorReport, AtomicLong isUnExecute) {
for (StepTreeDTO step : dtoList) {
if (step.getValue() != null) {
if (step.getValue() instanceof RequestResultExpandDTO
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), "unexecute")) {
&& StringUtils.equalsIgnoreCase(((RequestResultExpandDTO) step.getValue()).getStatus(), ExecuteResult.unexecute.name())) {
isUnExecute.set(isUnExecute.longValue() + 1);
} else if (step.getValue().getError() > 0 || !step.getValue().isSuccess()) {
isError.set(isError.longValue() + 1);
@ -628,4 +648,14 @@ public class ApiScenarioReportStructureService {
}
}
}
public RequestResult selectReportContent(String stepId) {
ApiScenarioReportResult apiScenarioReportResult = reportResultMapper.selectByPrimaryKey(stepId);
if (apiScenarioReportResult != null) {
RequestResult requestResult = JSON.parseObject(new String(apiScenarioReportResult.getContent(), StandardCharsets.UTF_8), RequestResult.class);
return requestResult;
} else {
return new RequestResultExpandDTO();
}
}
}

View File

@ -23,6 +23,18 @@ public class ApiScenarioReportResult implements Serializable {
private String errorCode;
private String reqName;
private Boolean reqSuccess;
private Integer reqError;
private Long reqStartTime;
private String rspCode;
private Long rspTime;
private byte[] content;
private static final long serialVersionUID = 1L;

View File

@ -693,6 +693,386 @@ public class ApiScenarioReportResultExample {
addCriterion("error_code not between", value1, value2, "errorCode");
return (Criteria) this;
}
public Criteria andReqNameIsNull() {
addCriterion("req_name is null");
return (Criteria) this;
}
public Criteria andReqNameIsNotNull() {
addCriterion("req_name is not null");
return (Criteria) this;
}
public Criteria andReqNameEqualTo(String value) {
addCriterion("req_name =", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameNotEqualTo(String value) {
addCriterion("req_name <>", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameGreaterThan(String value) {
addCriterion("req_name >", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameGreaterThanOrEqualTo(String value) {
addCriterion("req_name >=", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameLessThan(String value) {
addCriterion("req_name <", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameLessThanOrEqualTo(String value) {
addCriterion("req_name <=", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameLike(String value) {
addCriterion("req_name like", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameNotLike(String value) {
addCriterion("req_name not like", value, "reqName");
return (Criteria) this;
}
public Criteria andReqNameIn(List<String> values) {
addCriterion("req_name in", values, "reqName");
return (Criteria) this;
}
public Criteria andReqNameNotIn(List<String> values) {
addCriterion("req_name not in", values, "reqName");
return (Criteria) this;
}
public Criteria andReqNameBetween(String value1, String value2) {
addCriterion("req_name between", value1, value2, "reqName");
return (Criteria) this;
}
public Criteria andReqNameNotBetween(String value1, String value2) {
addCriterion("req_name not between", value1, value2, "reqName");
return (Criteria) this;
}
public Criteria andReqSuccessIsNull() {
addCriterion("req_success is null");
return (Criteria) this;
}
public Criteria andReqSuccessIsNotNull() {
addCriterion("req_success is not null");
return (Criteria) this;
}
public Criteria andReqSuccessEqualTo(Boolean value) {
addCriterion("req_success =", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessNotEqualTo(Boolean value) {
addCriterion("req_success <>", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessGreaterThan(Boolean value) {
addCriterion("req_success >", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessGreaterThanOrEqualTo(Boolean value) {
addCriterion("req_success >=", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessLessThan(Boolean value) {
addCriterion("req_success <", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessLessThanOrEqualTo(Boolean value) {
addCriterion("req_success <=", value, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessIn(List<Boolean> values) {
addCriterion("req_success in", values, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessNotIn(List<Boolean> values) {
addCriterion("req_success not in", values, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessBetween(Boolean value1, Boolean value2) {
addCriterion("req_success between", value1, value2, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqSuccessNotBetween(Boolean value1, Boolean value2) {
addCriterion("req_success not between", value1, value2, "reqSuccess");
return (Criteria) this;
}
public Criteria andReqErrorIsNull() {
addCriterion("req_error is null");
return (Criteria) this;
}
public Criteria andReqErrorIsNotNull() {
addCriterion("req_error is not null");
return (Criteria) this;
}
public Criteria andReqErrorEqualTo(Integer value) {
addCriterion("req_error =", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorNotEqualTo(Integer value) {
addCriterion("req_error <>", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorGreaterThan(Integer value) {
addCriterion("req_error >", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorGreaterThanOrEqualTo(Integer value) {
addCriterion("req_error >=", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorLessThan(Integer value) {
addCriterion("req_error <", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorLessThanOrEqualTo(Integer value) {
addCriterion("req_error <=", value, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorIn(List<Integer> values) {
addCriterion("req_error in", values, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorNotIn(List<Integer> values) {
addCriterion("req_error not in", values, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorBetween(Integer value1, Integer value2) {
addCriterion("req_error between", value1, value2, "reqError");
return (Criteria) this;
}
public Criteria andReqErrorNotBetween(Integer value1, Integer value2) {
addCriterion("req_error not between", value1, value2, "reqError");
return (Criteria) this;
}
public Criteria andReqStartTimeIsNull() {
addCriterion("req_start_time is null");
return (Criteria) this;
}
public Criteria andReqStartTimeIsNotNull() {
addCriterion("req_start_time is not null");
return (Criteria) this;
}
public Criteria andReqStartTimeEqualTo(Long value) {
addCriterion("req_start_time =", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeNotEqualTo(Long value) {
addCriterion("req_start_time <>", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeGreaterThan(Long value) {
addCriterion("req_start_time >", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeGreaterThanOrEqualTo(Long value) {
addCriterion("req_start_time >=", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeLessThan(Long value) {
addCriterion("req_start_time <", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeLessThanOrEqualTo(Long value) {
addCriterion("req_start_time <=", value, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeIn(List<Long> values) {
addCriterion("req_start_time in", values, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeNotIn(List<Long> values) {
addCriterion("req_start_time not in", values, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeBetween(Long value1, Long value2) {
addCriterion("req_start_time between", value1, value2, "reqStartTime");
return (Criteria) this;
}
public Criteria andReqStartTimeNotBetween(Long value1, Long value2) {
addCriterion("req_start_time not between", value1, value2, "reqStartTime");
return (Criteria) this;
}
public Criteria andRspCodeIsNull() {
addCriterion("rsp_code is null");
return (Criteria) this;
}
public Criteria andRspCodeIsNotNull() {
addCriterion("rsp_code is not null");
return (Criteria) this;
}
public Criteria andRspCodeEqualTo(String value) {
addCriterion("rsp_code =", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeNotEqualTo(String value) {
addCriterion("rsp_code <>", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeGreaterThan(String value) {
addCriterion("rsp_code >", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeGreaterThanOrEqualTo(String value) {
addCriterion("rsp_code >=", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeLessThan(String value) {
addCriterion("rsp_code <", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeLessThanOrEqualTo(String value) {
addCriterion("rsp_code <=", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeLike(String value) {
addCriterion("rsp_code like", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeNotLike(String value) {
addCriterion("rsp_code not like", value, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeIn(List<String> values) {
addCriterion("rsp_code in", values, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeNotIn(List<String> values) {
addCriterion("rsp_code not in", values, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeBetween(String value1, String value2) {
addCriterion("rsp_code between", value1, value2, "rspCode");
return (Criteria) this;
}
public Criteria andRspCodeNotBetween(String value1, String value2) {
addCriterion("rsp_code not between", value1, value2, "rspCode");
return (Criteria) this;
}
public Criteria andRspTimeIsNull() {
addCriterion("rsp_time is null");
return (Criteria) this;
}
public Criteria andRspTimeIsNotNull() {
addCriterion("rsp_time is not null");
return (Criteria) this;
}
public Criteria andRspTimeEqualTo(Long value) {
addCriterion("rsp_time =", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeNotEqualTo(Long value) {
addCriterion("rsp_time <>", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeGreaterThan(Long value) {
addCriterion("rsp_time >", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeGreaterThanOrEqualTo(Long value) {
addCriterion("rsp_time >=", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeLessThan(Long value) {
addCriterion("rsp_time <", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeLessThanOrEqualTo(Long value) {
addCriterion("rsp_time <=", value, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeIn(List<Long> values) {
addCriterion("rsp_time in", values, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeNotIn(List<Long> values) {
addCriterion("rsp_time not in", values, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeBetween(Long value1, Long value2) {
addCriterion("rsp_time between", value1, value2, "rspTime");
return (Criteria) this;
}
public Criteria andRspTimeNotBetween(Long value1, Long value2) {
addCriterion("rsp_time not between", value1, value2, "rspTime");
return (Criteria) this;
}
}
public static class Criteria extends GeneratedCriteria {

View File

@ -11,6 +11,12 @@
<result column="total_assertions" jdbcType="BIGINT" property="totalAssertions" />
<result column="pass_assertions" jdbcType="BIGINT" property="passAssertions" />
<result column="error_code" jdbcType="VARCHAR" property="errorCode" />
<result column="req_name" jdbcType="VARCHAR" property="reqName" />
<result column="req_success" jdbcType="BIT" property="reqSuccess" />
<result column="req_error" jdbcType="INTEGER" property="reqError" />
<result column="req_start_time" jdbcType="BIGINT" property="reqStartTime" />
<result column="rsp_code" jdbcType="VARCHAR" property="rspCode" />
<result column="rsp_time" jdbcType="BIGINT" property="rspTime" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.ApiScenarioReportResult">
<result column="content" jdbcType="LONGVARBINARY" property="content" />
@ -75,7 +81,8 @@
</sql>
<sql id="Base_Column_List">
id, resource_id, report_id, create_time, `status`, request_time, total_assertions,
pass_assertions, error_code
pass_assertions, error_code, req_name, req_success, req_error, req_start_time, rsp_code,
rsp_time
</sql>
<sql id="Blob_Column_List">
content
@ -132,10 +139,14 @@
insert into api_scenario_report_result (id, resource_id, report_id,
create_time, `status`, request_time,
total_assertions, pass_assertions, error_code,
req_name, req_success, req_error,
req_start_time, rsp_code, rsp_time,
content)
values (#{id,jdbcType=VARCHAR}, #{resourceId,jdbcType=VARCHAR}, #{reportId,jdbcType=VARCHAR},
#{createTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR}, #{requestTime,jdbcType=BIGINT},
#{totalAssertions,jdbcType=BIGINT}, #{passAssertions,jdbcType=BIGINT}, #{errorCode,jdbcType=VARCHAR},
#{reqName,jdbcType=VARCHAR}, #{reqSuccess,jdbcType=BIT}, #{reqError,jdbcType=INTEGER},
#{reqStartTime,jdbcType=BIGINT}, #{rspCode,jdbcType=VARCHAR}, #{rspTime,jdbcType=BIGINT},
#{content,jdbcType=LONGVARBINARY})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.ApiScenarioReportResult">
@ -168,6 +179,24 @@
<if test="errorCode != null">
error_code,
</if>
<if test="reqName != null">
req_name,
</if>
<if test="reqSuccess != null">
req_success,
</if>
<if test="reqError != null">
req_error,
</if>
<if test="reqStartTime != null">
req_start_time,
</if>
<if test="rspCode != null">
rsp_code,
</if>
<if test="rspTime != null">
rsp_time,
</if>
<if test="content != null">
content,
</if>
@ -200,6 +229,24 @@
<if test="errorCode != null">
#{errorCode,jdbcType=VARCHAR},
</if>
<if test="reqName != null">
#{reqName,jdbcType=VARCHAR},
</if>
<if test="reqSuccess != null">
#{reqSuccess,jdbcType=BIT},
</if>
<if test="reqError != null">
#{reqError,jdbcType=INTEGER},
</if>
<if test="reqStartTime != null">
#{reqStartTime,jdbcType=BIGINT},
</if>
<if test="rspCode != null">
#{rspCode,jdbcType=VARCHAR},
</if>
<if test="rspTime != null">
#{rspTime,jdbcType=BIGINT},
</if>
<if test="content != null">
#{content,jdbcType=LONGVARBINARY},
</if>
@ -241,6 +288,24 @@
<if test="record.errorCode != null">
error_code = #{record.errorCode,jdbcType=VARCHAR},
</if>
<if test="record.reqName != null">
req_name = #{record.reqName,jdbcType=VARCHAR},
</if>
<if test="record.reqSuccess != null">
req_success = #{record.reqSuccess,jdbcType=BIT},
</if>
<if test="record.reqError != null">
req_error = #{record.reqError,jdbcType=INTEGER},
</if>
<if test="record.reqStartTime != null">
req_start_time = #{record.reqStartTime,jdbcType=BIGINT},
</if>
<if test="record.rspCode != null">
rsp_code = #{record.rspCode,jdbcType=VARCHAR},
</if>
<if test="record.rspTime != null">
rsp_time = #{record.rspTime,jdbcType=BIGINT},
</if>
<if test="record.content != null">
content = #{record.content,jdbcType=LONGVARBINARY},
</if>
@ -260,6 +325,12 @@
total_assertions = #{record.totalAssertions,jdbcType=BIGINT},
pass_assertions = #{record.passAssertions,jdbcType=BIGINT},
error_code = #{record.errorCode,jdbcType=VARCHAR},
req_name = #{record.reqName,jdbcType=VARCHAR},
req_success = #{record.reqSuccess,jdbcType=BIT},
req_error = #{record.reqError,jdbcType=INTEGER},
req_start_time = #{record.reqStartTime,jdbcType=BIGINT},
rsp_code = #{record.rspCode,jdbcType=VARCHAR},
rsp_time = #{record.rspTime,jdbcType=BIGINT},
content = #{record.content,jdbcType=LONGVARBINARY}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -275,7 +346,13 @@
request_time = #{record.requestTime,jdbcType=BIGINT},
total_assertions = #{record.totalAssertions,jdbcType=BIGINT},
pass_assertions = #{record.passAssertions,jdbcType=BIGINT},
error_code = #{record.errorCode,jdbcType=VARCHAR}
error_code = #{record.errorCode,jdbcType=VARCHAR},
req_name = #{record.reqName,jdbcType=VARCHAR},
req_success = #{record.reqSuccess,jdbcType=BIT},
req_error = #{record.reqError,jdbcType=INTEGER},
req_start_time = #{record.reqStartTime,jdbcType=BIGINT},
rsp_code = #{record.rspCode,jdbcType=VARCHAR},
rsp_time = #{record.rspTime,jdbcType=BIGINT}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
</if>
@ -307,6 +384,24 @@
<if test="errorCode != null">
error_code = #{errorCode,jdbcType=VARCHAR},
</if>
<if test="reqName != null">
req_name = #{reqName,jdbcType=VARCHAR},
</if>
<if test="reqSuccess != null">
req_success = #{reqSuccess,jdbcType=BIT},
</if>
<if test="reqError != null">
req_error = #{reqError,jdbcType=INTEGER},
</if>
<if test="reqStartTime != null">
req_start_time = #{reqStartTime,jdbcType=BIGINT},
</if>
<if test="rspCode != null">
rsp_code = #{rspCode,jdbcType=VARCHAR},
</if>
<if test="rspTime != null">
rsp_time = #{rspTime,jdbcType=BIGINT},
</if>
<if test="content != null">
content = #{content,jdbcType=LONGVARBINARY},
</if>
@ -323,6 +418,12 @@
total_assertions = #{totalAssertions,jdbcType=BIGINT},
pass_assertions = #{passAssertions,jdbcType=BIGINT},
error_code = #{errorCode,jdbcType=VARCHAR},
req_name = #{reqName,jdbcType=VARCHAR},
req_success = #{reqSuccess,jdbcType=BIT},
req_error = #{reqError,jdbcType=INTEGER},
req_start_time = #{reqStartTime,jdbcType=BIGINT},
rsp_code = #{rspCode,jdbcType=VARCHAR},
rsp_time = #{rspTime,jdbcType=BIGINT},
content = #{content,jdbcType=LONGVARBINARY}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -335,7 +436,13 @@
request_time = #{requestTime,jdbcType=BIGINT},
total_assertions = #{totalAssertions,jdbcType=BIGINT},
pass_assertions = #{passAssertions,jdbcType=BIGINT},
error_code = #{errorCode,jdbcType=VARCHAR}
error_code = #{errorCode,jdbcType=VARCHAR},
req_name = #{reqName,jdbcType=VARCHAR},
req_success = #{reqSuccess,jdbcType=BIT},
req_error = #{reqError,jdbcType=INTEGER},
req_start_time = #{reqStartTime,jdbcType=BIGINT},
rsp_code = #{rspCode,jdbcType=VARCHAR},
rsp_time = #{rspTime,jdbcType=BIGINT}
where id = #{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -0,0 +1,9 @@
package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.ApiScenarioReportResult;
import java.util.List;
public interface ExtApiScenarioReportResultMapper {
List<ApiScenarioReportResult> selectBaseInfoResultByReportId(String reportId);
}

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.metersphere.base.mapper.ext.ExtApiScenarioReportResultMapper">
<select id="selectBaseInfoResultByReportId" resultType="io.metersphere.base.domain.ApiScenarioReportResult">
SELECT id,
resource_id,
report_id,
create_time,
status,
request_time,
total_assertions,
pass_assertions,
error_code,
req_name,
req_success,
req_error,
req_start_time,
rsp_code,
rsp_time
FROM api_scenario_report_result
WHERE report_id = #{0}
</select>
</mapper>

View File

@ -7,6 +7,9 @@ public enum ExecuteResult {
//接口执行状态(兼容旧数据)
success,error,
//未执行状态
unexecute,
//场景执行状态(兼容旧数据)
Success,Error,

@ -1 +1 @@
Subproject commit 55fa4531900451835f746ffe1f5e0ea311080cac
Subproject commit 7aacf4701c86ebe5d31c42d6b84685a2ea20e4df

View File

@ -178,5 +178,12 @@ CREATE TABLE IF NOT EXISTS `test_plan_execution_queue`
KEY `report_id_idx` (`report_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci;
-- 场景步骤结果增加简要信息
ALTER TABLE api_scenario_report_result ADD (
`req_name` VARCHAR(255) NULL,
`req_success` tinyint(1) NULL DEFAULT 0,
`req_error` int(11) NULL DEFAULT 0,
`req_start_time` bigint(13) NULL DEFAULT NULL,
`rsp_code` VARCHAR(255) NULL,
`rsp_time` bigint(13) NULL DEFAULT NULL
);

View File

@ -70,9 +70,10 @@
<el-collapse-transition>
<div v-show="showActive && !request.unexecute" style="width: 99%">
<ms-request-result-tail
v-loading="requestInfo.loading"
:scenario-name="scenarioName"
:request-type="requestType"
:request="request"
:request="requestInfo"
:console="console"
v-if="showActive"/>
</div>
@ -100,6 +101,7 @@ export default {
props: {
request: Object,
scenarioName: String,
stepId: String,
indexNumber: Number,
console: String,
errorCode: {
@ -124,6 +126,12 @@ export default {
return "#B8741A";
}
},
requestInfo: {
loading: true,
hasData: false,
responseResult: {},
subRequestResults: [],
},
baseErrorCode: "",
backgroundColor: {
type: String,
@ -155,12 +163,31 @@ export default {
}
},
methods: {
loadRequestInfoExpand() {
this.$get("/api/scenario/report/selectReportContent/" + this.stepId, response => {
let requestResult = response.data;
if (requestResult) {
this.requestInfo = requestResult;
}
this.$nextTick(() => {
this.requestInfo.loading = false;
this.requestInfo.hasData = true;
});
});
},
active() {
if (this.request.unexecute) {
this.showActive = false;
} else {
this.showActive = !this.showActive;
}
if (this.showActive) {
if (this.requestInfo.hasData) {
this.requestInfo.loading = false;
} else {
this.loadRequestInfoExpand();
}
}
},
getName(name) {
if (name && name.indexOf("<->") !== -1) {

View File

@ -21,6 +21,7 @@
</div>
<div v-else>
<ms-request-result
:step-id="node.stepId"
:request="node.value"
:indexNumber="node.index"
:error-code="node.errorCode"