feat(接口测试): 执行误报处理

This commit is contained in:
fit2-zhao 2024-02-03 15:45:17 +08:00 committed by Craftsman
parent c6a73e6804
commit 9269aba07b
9 changed files with 167 additions and 20 deletions

View File

@ -0,0 +1,11 @@
package io.metersphere.sdk.dto.api.result;
import lombok.Data;
@Data
public class FakeErrorDTO {
private String projectId;
private boolean higherThanSuccess;
private boolean higherThanError;
}

View File

@ -1,12 +1,32 @@
package io.metersphere.sdk.dto.api.result;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
public class MsRegexDTO {
private String subject;
private String condition;
private String value;
private String errorCode;
private boolean pass;
public class MsRegexDTO implements Serializable {
// 项目ID
private String projectId;
// 误报名称
private String name;
// 匹配类型/文本内容
private String type;
// 响应内容类型/header/data/body
private String respType;
// 操作类型/大于/等于/小于
private String relation;
// 表达式
private String expression;
private Boolean pass;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -15,6 +15,11 @@ public class RequestResult {
*/
private String resourceId;
/**
* 项目ID
*/
private String projectId;
/**
* 步骤请求唯一ID
*/
@ -109,11 +114,6 @@ public class RequestResult {
this.passAssertionsTotal++;
}
/**
* 误报信息
*/
private String fakeErrorMessage;
/**
* 误报编码名称
*/

View File

@ -6,7 +6,6 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 任务请求参数数据
@ -42,6 +41,7 @@ public class TaskRequestDTO implements Serializable {
/**
* 资源类型
*
* @see io.metersphere.sdk.constants.ApiExecuteResourceType
*/
private String resourceType;
@ -63,7 +63,7 @@ public class TaskRequestDTO implements Serializable {
/**
* 误报规则
*/
Map<String, List<MsRegexDTO>> fakeErrorMap;
List<MsRegexDTO> msRegexList;
/**
* 项目id

View File

@ -0,0 +1,87 @@
package io.metersphere.sdk.util.fake.error;
import io.metersphere.sdk.constants.ApiReportStatus;
import io.metersphere.sdk.dto.api.result.MsRegexDTO;
import io.metersphere.sdk.dto.api.result.RequestResult;
import io.metersphere.sdk.util.LogUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 误报解析类
*/
public class FakeErrorUtils {
public static void compute(RequestResult result, List<MsRegexDTO> regexDTOS) {
try {
if (result != null && StringUtils.isNotBlank(result.getProjectId()) &&
CollectionUtils.isNotEmpty(regexDTOS)) {
Map<String, List<MsRegexDTO>> fakeErrorMap = regexDTOS.stream()
.collect(Collectors.groupingBy(MsRegexDTO::getProjectId));
List<MsRegexDTO> regexList = fakeErrorMap.get(result.getProjectId());
//根据配置来筛选断言获取误报编码获取接口状态是否是误报
List<String> errorCodeList = new ArrayList<>();
regexList.forEach(item -> {
if (StringUtils.isNotEmpty(item.getType())) {
switch (item.getRespType()) {
case "Response Code" ->
item.setPass(parseResponseCode(result.getResponseResult().getResponseCode(), item.getExpression(), item.getRelation()));
case "Response Headers" ->
item.setPass(parseResponseCode(result.getResponseResult().getHeaders(), item.getExpression(), item.getRelation()));
case "Response Data" ->
item.setPass(parseResponseCode(result.getResponseResult().getBody(), item.getExpression(), item.getRelation()));
default -> item.setPass(false);
}
}
if (BooleanUtils.isTrue(item.getPass())) {
errorCodeList.add(item.getName());
}
});
if (CollectionUtils.isNotEmpty(errorCodeList)) {
result.setStatus(ApiReportStatus.FAKE_ERROR.name());
result.setFakeErrorCode(getErrorCodeStr(errorCodeList));
}
}
} catch (Exception e) {
LogUtils.error("误报处理错误:", e);
}
}
private static boolean parseResponseCode(String result, String regexDTO, String condition) {
return switch (condition.toUpperCase()) {
case "CONTAINS" -> result.contains(regexDTO);
case "NOT_CONTAINS" -> notContains(result, regexDTO);
case "EQUALS" -> StringUtils.equals(result, regexDTO);
case "START_WITH" -> result.startsWith(regexDTO);
case "END_WITH" -> result.endsWith(regexDTO);
default -> false;
};
}
private static String getErrorCodeStr(List<String> errorCodeList) {
if (CollectionUtils.isNotEmpty(errorCodeList)) {
String errorCodeStr = StringUtils.join(errorCodeList, ";");
return errorCodeStr;
} else {
return StringUtils.EMPTY;
}
}
private static boolean notContains(String result, String regexDTO) {
return !result.contains(regexDTO);
}
}

View File

@ -7,9 +7,9 @@ import io.metersphere.api.parser.jmeter.body.MsBodyConverter;
import io.metersphere.api.parser.jmeter.body.MsBodyConverterFactory;
import io.metersphere.api.parser.jmeter.body.MsFormDataBodyConverter;
import io.metersphere.api.parser.jmeter.body.MsWWWFormBodyConverter;
import io.metersphere.plugin.api.constants.ElementProperty;
import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
import io.metersphere.plugin.api.constants.ElementProperty;
import io.metersphere.sdk.util.LogUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@ -47,7 +47,6 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
sampler.setProperty(ElementProperty.MS_RESOURCE_ID.name(), msHTTPElement.getResourceId());
sampler.setProperty(ElementProperty.MS_STEP_ID.name(), msHTTPElement.getStepId());
sampler.setProperty(ElementProperty.MS_REPORT_ID.name(), config.getReportId());
sampler.setMethod(msHTTPElement.getMethod());
// todo 根据环境设置
sampler.setDomain(msHTTPElement.getUrl());

View File

@ -24,7 +24,11 @@ import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo;
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.*;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.EncryptUtils;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.LogUtils;
import io.metersphere.system.config.MinioProperties;
import io.metersphere.system.domain.TestResourcePool;
import io.metersphere.system.dto.pool.TestResourceDTO;
@ -44,7 +48,12 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static io.metersphere.api.controller.result.ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR;
@ -120,7 +129,9 @@ public class ApiExecuteService {
// 设置执行文件参数
setTaskFileParam(request, taskRequest);
// todo 误报
// 误报处理
taskRequest.setMsRegexList(projectApplicationService.get(Arrays.asList(request.getProjectId())));
// todo 获取接口插件和jar包
// todo 处理公共脚本
// todo 接口用例 method 获取定义中的数据库字段

View File

@ -95,7 +95,7 @@ public class FakeErrorService {
FakeErrorExample example = new FakeErrorExample();
FakeErrorExample.Criteria criteria = example.createCriteria();
criteria.andProjectIdEqualTo(item.getProjectId()).andNameEqualTo(item.getName());
if (StringUtils.isNotBlank(item.getId()) && StringUtils.equalsIgnoreCase(type,UPDATE_TYPE)) {
if (StringUtils.isNotBlank(item.getId()) && StringUtils.equalsIgnoreCase(type, UPDATE_TYPE)) {
criteria.andIdNotEqualTo(item.getId());
}
if (fakeErrorMapper.countByExample(example) > 0) {

View File

@ -3,6 +3,7 @@ package io.metersphere.project.service;
import io.metersphere.plugin.platform.spi.AbstractPlatformPlugin;
import io.metersphere.plugin.platform.spi.Platform;
import io.metersphere.plugin.sdk.spi.MsPlugin;
import io.metersphere.project.domain.FakeError;
import io.metersphere.project.domain.FakeErrorExample;
import io.metersphere.project.domain.Project;
import io.metersphere.project.domain.ProjectApplication;
@ -13,7 +14,9 @@ import io.metersphere.project.request.ProjectApplicationRequest;
import io.metersphere.project.utils.ModuleSortUtils;
import io.metersphere.sdk.constants.OperationLogConstants;
import io.metersphere.sdk.constants.ProjectApplicationType;
import io.metersphere.sdk.dto.api.result.MsRegexDTO;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.sdk.util.Translator;
@ -473,6 +476,22 @@ public class ProjectApplicationService {
return (int) l;
}
public List<MsRegexDTO> get(List<String> projectIds) {
List<MsRegexDTO> regexList = new ArrayList<>();
if (CollectionUtils.isEmpty(projectIds)) {
return regexList;
}
FakeErrorExample example = new FakeErrorExample();
example.createCriteria().andProjectIdIn(projectIds).andEnableEqualTo(true);
List<FakeError> fakeErrors = fakeErrorMapper.selectByExample(example);
fakeErrors.forEach(item -> {
MsRegexDTO regexConfig = new MsRegexDTO();
BeanUtils.copyBean(regexConfig, item);
regexList.add(regexConfig);
});
return regexList;
}
/**
* 获取缺陷项目配置信息