refactor(接口测试): 优化请求体参数

This commit is contained in:
AgAngle 2024-02-05 16:55:23 +08:00 committed by Craftsman
parent bffd717e93
commit c8e70124db
13 changed files with 53 additions and 50 deletions

View File

@ -3,6 +3,8 @@ package io.metersphere.api.dto.request.http;
import io.metersphere.api.dto.request.http.auth.HTTPAuth; import io.metersphere.api.dto.request.http.auth.HTTPAuth;
import io.metersphere.api.dto.request.http.body.Body; import io.metersphere.api.dto.request.http.body.Body;
import io.metersphere.plugin.api.spi.AbstractMsTestElement; import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
@ -34,9 +36,11 @@ public class MsHTTPElement extends AbstractMsTestElement {
private String path; private String path;
/** /**
* 请求方法 * 请求方法
* 取值参考{@link HttpMethodConstants}
*/ */
@NotBlank @NotBlank
@Size(max = 10) @Size(max = 10)
@EnumValue(enumClass = HttpMethodConstants.class)
private String method; private String method;
/** /**
* 请求体 * 请求体

View File

@ -13,5 +13,5 @@ public class FormDataBody {
/** /**
* form-data 请求体的键值对列表 * form-data 请求体的键值对列表
*/ */
private List<FormDataKV> fromValues; private List<FormDataKV> formValues;
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.api.dto.request.http.body;
import io.metersphere.api.dto.ApiFile; import io.metersphere.api.dto.ApiFile;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.Data; import lombok.Data;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -22,6 +23,11 @@ public class FormDataKV extends WWWFormKV {
*/ */
@Valid @Valid
private List<ApiFile> files; private List<ApiFile> files;
/**
* 参数的 contentType
*/
@Size(max = 100)
private String contentType;
public boolean isFile() { public boolean isFile() {
return StringUtils.equalsIgnoreCase(getParamType(), BodyParamType.FILE.getValue()); return StringUtils.equalsIgnoreCase(getParamType(), BodyParamType.FILE.getValue());

View File

@ -13,5 +13,5 @@ import java.util.List;
@Data @Data
public class WWWFormBody { public class WWWFormBody {
@Valid @Valid
private List<FormDataKV> fromValues; private List<WWWFormKV> formValues;
} }

View File

@ -34,11 +34,6 @@ public class WWWFormKV extends KeyValueEnableParam {
* 最大长度 * 最大长度
*/ */
private Integer maxLength; private Integer maxLength;
/**
* 参数的 contentType
*/
@Size(max = 100)
private String contentType;
/** /**
* 是否对参数进行编码 * 是否对参数进行编码
* 默认 false * 默认 false

View File

@ -166,7 +166,7 @@ public class Swagger3Parser<T> implements ImportParser<ApiDefinitionImport> {
private void parseWWWFormBody(JsonSchemaItem item, Body body) { private void parseWWWFormBody(JsonSchemaItem item, Body body) {
WWWFormBody wwwFormBody = new WWWFormBody(); WWWFormBody wwwFormBody = new WWWFormBody();
List<String> required = item.getRequired(); List<String> required = item.getRequired();
List<FormDataKV> formDataKVS = new ArrayList<>(); List<WWWFormKV> formDataKVS = new ArrayList<>();
item.getProperties().forEach((key, value) -> { item.getProperties().forEach((key, value) -> {
if (value != null && !StringUtils.equals(PropertyConstant.OBJECT, value.getType())) { if (value != null && !StringUtils.equals(PropertyConstant.OBJECT, value.getType())) {
FormDataKV formDataKV = new FormDataKV(); FormDataKV formDataKV = new FormDataKV();
@ -180,7 +180,7 @@ public class Swagger3Parser<T> implements ImportParser<ApiDefinitionImport> {
formDataKVS.add(formDataKV); formDataKVS.add(formDataKV);
} }
}); });
wwwFormBody.setFromValues(formDataKVS); wwwFormBody.setFormValues(formDataKVS);
body.setWwwFormBody(wwwFormBody); body.setWwwFormBody(wwwFormBody);
} }

View File

@ -2,6 +2,7 @@ package io.metersphere.api.parser.jmeter.body;
import io.metersphere.api.dto.ApiFile; import io.metersphere.api.dto.ApiFile;
import io.metersphere.api.dto.request.http.body.FormDataKV;
import io.metersphere.api.dto.request.http.body.WWWFormKV; import io.metersphere.api.dto.request.http.body.WWWFormKV;
import io.metersphere.jmeter.mock.Mock; import io.metersphere.jmeter.mock.Mock;
import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.dto.ParameterConfig;
@ -36,23 +37,23 @@ public abstract class MsBodyConverter<T> {
/** /**
* 解析文本类型的 kv 参数 * 解析文本类型的 kv 参数
* @param textFromValues * @param textFormValues
* @return * @return
*/ */
protected Arguments getArguments(List<? extends WWWFormKV> textFromValues) { protected Arguments getArguments(List<? extends WWWFormKV> textFormValues) {
Arguments arguments = new Arguments(); Arguments arguments = new Arguments();
textFromValues.forEach(formDataKV -> { textFormValues.forEach(kv -> {
// 处理 mock 函数 // 处理 mock 函数
String value = Mock.buildFunctionCallString(formDataKV.getValue()); String value = Mock.buildFunctionCallString(kv.getValue());
if (value == null) { if (value == null) {
value = StringUtils.EMPTY; value = StringUtils.EMPTY;
} }
HTTPArgument httpArgument = new HTTPArgument(formDataKV.getKey(), value); HTTPArgument httpArgument = new HTTPArgument(kv.getKey(), value);
httpArgument.setAlwaysEncoded(formDataKV.getEncode()); httpArgument.setAlwaysEncoded(kv.getEncode());
if (StringUtils.isNotBlank(formDataKV.getContentType())) { arguments.addArgument(httpArgument);
if (kv instanceof FormDataKV formDataKV && formDataKV.getContentType() != null) {
httpArgument.setContentType(formDataKV.getContentType()); httpArgument.setContentType(formDataKV.getContentType());
} }
arguments.addArgument(httpArgument);
}); });
return arguments; return arguments;
} }

View File

@ -22,29 +22,29 @@ public class MsFormDataBodyConverter extends MsBodyConverter<FormDataBody> {
@Override @Override
public void parse(HTTPSamplerProxy sampler, FormDataBody body, ParameterConfig config) { public void parse(HTTPSamplerProxy sampler, FormDataBody body, ParameterConfig config) {
List<FormDataKV> fromValues = body.getFromValues(); List<FormDataKV> formValues = body.getFormValues();
List<FormDataKV> validFromValues = fromValues.stream().filter(FormDataKV::isValid).collect(Collectors.toList()); List<FormDataKV> validFormValues = formValues.stream().filter(FormDataKV::isValid).collect(Collectors.toList());
List<FormDataKV> fileFromValues = validFromValues.stream().filter(FormDataKV::isFile).collect(Collectors.toList()); List<FormDataKV> fileFormValues = validFormValues.stream().filter(FormDataKV::isFile).collect(Collectors.toList());
List<FormDataKV> textFromValues = validFromValues.stream().filter(kv -> !kv.isFile()).collect(Collectors.toList()); List<FormDataKV> textFormValues = validFormValues.stream().filter(kv -> !kv.isFile()).collect(Collectors.toList());
sampler.setDoMultipart(true); sampler.setDoMultipart(true);
sampler.setHTTPFiles(getHttpFileArg(fileFromValues)); sampler.setHTTPFiles(getHttpFileArg(fileFormValues));
sampler.setArguments(getArguments(textFromValues)); sampler.setArguments(getArguments(textFormValues));
} }
/** /**
* 解析文件类型的参数 * 解析文件类型的参数
* *
* @param fileFromValues * @param fileFormValues
* @return * @return
*/ */
private HTTPFileArg[] getHttpFileArg(List<FormDataKV> fileFromValues) { private HTTPFileArg[] getHttpFileArg(List<FormDataKV> fileFormValues) {
if (CollectionUtils.isEmpty(fileFromValues)) { if (CollectionUtils.isEmpty(fileFormValues)) {
return new HTTPFileArg[0]; return new HTTPFileArg[0];
} }
List<HTTPFileArg> list = new ArrayList<>(); List<HTTPFileArg> list = new ArrayList<>();
if (CollectionUtils.isNotEmpty(fileFromValues)) { if (CollectionUtils.isNotEmpty(fileFormValues)) {
fileFromValues.forEach(formDataKV -> { fileFormValues.forEach(formDataKV -> {
String paramName = formDataKV.getKey(); String paramName = formDataKV.getKey();
formDataKV.getFiles().forEach(file -> { formDataKV.getFiles().forEach(file -> {
HTTPFileArg fileArg = getHttpFileArg(file); HTTPFileArg fileArg = getHttpFileArg(file);

View File

@ -1,7 +1,7 @@
package io.metersphere.api.parser.jmeter.body; package io.metersphere.api.parser.jmeter.body;
import io.metersphere.api.dto.request.http.body.FormDataKV;
import io.metersphere.api.dto.request.http.body.WWWFormBody; import io.metersphere.api.dto.request.http.body.WWWFormBody;
import io.metersphere.api.dto.request.http.body.WWWFormKV;
import io.metersphere.plugin.api.dto.ParameterConfig; import io.metersphere.plugin.api.dto.ParameterConfig;
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy; import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
@ -15,8 +15,8 @@ import java.util.stream.Collectors;
public class MsWWWFormBodyConverter extends MsBodyConverter<WWWFormBody> { public class MsWWWFormBodyConverter extends MsBodyConverter<WWWFormBody> {
@Override @Override
public void parse(HTTPSamplerProxy sampler, WWWFormBody body, ParameterConfig config) { public void parse(HTTPSamplerProxy sampler, WWWFormBody body, ParameterConfig config) {
List<FormDataKV> fromValues = body.getFromValues(); List<WWWFormKV> formValues = body.getFormValues();
List<FormDataKV> validFromValues = fromValues.stream().filter(FormDataKV::isValid).collect(Collectors.toList()); List<WWWFormKV> validFormValues = formValues.stream().filter(WWWFormKV::isValid).collect(Collectors.toList());
sampler.setArguments(getArguments(validFromValues)); sampler.setArguments(getArguments(validFormValues));
} }
} }

View File

@ -86,11 +86,11 @@ public class ApiStepParser extends StepParser {
} }
if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.FORM_DATA.name()) && if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.FORM_DATA.name()) &&
valueBody.getFormDataBody() != null && refBody.getFormDataBody() != null) { valueBody.getFormDataBody() != null && refBody.getFormDataBody() != null) {
replaceKvParam(valueBody.getFormDataBody().getFromValues(), valueBody.getFormDataBody().getFromValues()); replaceKvParam(valueBody.getFormDataBody().getFormValues(), valueBody.getFormDataBody().getFormValues());
} }
if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.WWW_FORM.name()) && if (StringUtils.equals(refBody.getBodyType(), Body.BodyType.WWW_FORM.name()) &&
valueBody.getWwwFormBody() != null && refBody.getWwwFormBody() != null) { valueBody.getWwwFormBody() != null && refBody.getWwwFormBody() != null) {
replaceKvParam(valueBody.getWwwFormBody().getFromValues(), valueBody.getWwwFormBody().getFromValues()); replaceKvParam(valueBody.getWwwFormBody().getFormValues(), valueBody.getWwwFormBody().getFormValues());
} }
// todo JsonSchema body // todo JsonSchema body
} }

View File

@ -517,11 +517,11 @@ public class ApiDefinitionImportUtilService {
FormDataBody formDataBody = dbbody.getFormDataBody(); FormDataBody formDataBody = dbbody.getFormDataBody();
FormDataBody importFormDataBody = importBody.getFormDataBody(); FormDataBody importFormDataBody = importBody.getFormDataBody();
if (ObjectUtils.isNotEmpty(formDataBody) || ObjectUtils.isNotEmpty(importFormDataBody)) { if (ObjectUtils.isNotEmpty(formDataBody) || ObjectUtils.isNotEmpty(importFormDataBody)) {
List<FormDataKV> fromValues = formDataBody.getFromValues(); List<FormDataKV> formValues = formDataBody.getFormValues();
List<FormDataKV> importFromValues = importFormDataBody.getFromValues(); List<FormDataKV> importFormValues = importFormDataBody.getFormValues();
if (CollectionUtils.isNotEmpty(fromValues) || CollectionUtils.isNotEmpty(importFromValues)) { if (CollectionUtils.isNotEmpty(formValues) || CollectionUtils.isNotEmpty(importFormValues)) {
List<String> dbFormKeys = fromValues.stream().map(FormDataKV::getKey).toList(); List<String> dbFormKeys = formValues.stream().map(FormDataKV::getKey).toList();
List<String> importFormKeys = importFromValues.stream().map(FormDataKV::getKey).toList(); List<String> importFormKeys = importFormValues.stream().map(FormDataKV::getKey).toList();
if (paramsIsSame(dbFormKeys, importFormKeys)) { if (paramsIsSame(dbFormKeys, importFormKeys)) {
return false; return false;
} }
@ -531,11 +531,11 @@ public class ApiDefinitionImportUtilService {
WWWFormBody wwwBody = dbbody.getWwwFormBody(); WWWFormBody wwwBody = dbbody.getWwwFormBody();
WWWFormBody importWwwBody = importBody.getWwwFormBody(); WWWFormBody importWwwBody = importBody.getWwwFormBody();
if (ObjectUtils.isNotEmpty(wwwBody) || ObjectUtils.isNotEmpty(importWwwBody)) { if (ObjectUtils.isNotEmpty(wwwBody) || ObjectUtils.isNotEmpty(importWwwBody)) {
List<FormDataKV> wwwValues = wwwBody.getFromValues(); List<WWWFormKV> wwwValues = wwwBody.getFormValues();
List<FormDataKV> importWwwValues = importWwwBody.getFromValues(); List<WWWFormKV> importWwwValues = importWwwBody.getFormValues();
if (CollectionUtils.isNotEmpty(wwwValues) || CollectionUtils.isNotEmpty(importWwwValues)) { if (CollectionUtils.isNotEmpty(wwwValues) || CollectionUtils.isNotEmpty(importWwwValues)) {
List<String> dbWwwKeys = wwwValues.stream().map(FormDataKV::getKey).toList(); List<String> dbWwwKeys = wwwValues.stream().map(WWWFormKV::getKey).toList();
List<String> importWwwKeys = importWwwValues.stream().map(FormDataKV::getKey).toList(); List<String> importWwwKeys = importWwwValues.stream().map(WWWFormKV::getKey).toList();
if (paramsIsSame(dbWwwKeys, importWwwKeys)) { if (paramsIsSame(dbWwwKeys, importWwwKeys)) {
return false; return false;
} }

View File

@ -79,11 +79,12 @@ public class MsHTTPElementTest {
bodyFile.setFileName("aaa"); bodyFile.setFileName("aaa");
formDataFileKV.setFiles(List.of(bodyFile)); formDataFileKV.setFiles(List.of(bodyFile));
formDataFileKV.setKey("fileKey"); formDataFileKV.setKey("fileKey");
formDataBody.setFromValues(List.of(formDataKV)); formDataBody.setFormValues(List.of(formDataKV));
body.setFormDataBody(formDataBody); body.setFormDataBody(formDataBody);
WWWFormKV wwwFormKV = BeanUtils.copyBean(new WWWFormKV(), formDataKV);
WWWFormBody wwwFormBody = new WWWFormBody(); WWWFormBody wwwFormBody = new WWWFormBody();
wwwFormBody.setFromValues(List.of(formDataKV)); wwwFormBody.setFormValues(List.of(wwwFormKV));
body.setWwwFormBody(wwwFormBody); body.setWwwFormBody(wwwFormBody);
JsonBody jsonBody = new JsonBody(); JsonBody jsonBody = new JsonBody();
@ -411,7 +412,7 @@ public class MsHTTPElementTest {
formDataKV.setRequired(true); formDataKV.setRequired(true);
formDataKV.setValue("value"); formDataKV.setValue("value");
formDataKV.setKey("key"); formDataKV.setKey("key");
formDataBody.setFromValues(List.of(formDataKV)); formDataBody.setFormValues(List.of(formDataKV));
Body body = new Body(); Body body = new Body();
body.setBodyType(Body.BodyType.FORM_DATA.name()); body.setBodyType(Body.BodyType.FORM_DATA.name());
httpResponse.setBody(body); httpResponse.setBody(body);

View File

@ -14,10 +14,6 @@ import java.util.List;
public class HttpConfig implements Serializable { public class HttpConfig implements Serializable {
@Schema(description = "环境域名") @Schema(description = "环境域名")
private String url; private String url;
@Schema(description = "接口测试")
private Boolean apiTest = true;
@Schema(description = "UI测试")
private Boolean uiTest = false;
@Schema(description = "启用条件 NONE/MODULE/PATH") @Schema(description = "启用条件 NONE/MODULE/PATH")
private String type = "NONE"; private String type = "NONE";
@Schema(description = "启用条件为PATH时需要填写的路径/ key为equal时value为路径key为contain时value为包含的路径") @Schema(description = "启用条件为PATH时需要填写的路径/ key为equal时value为路径key为contain时value为包含的路径")