feat(接口测试): 处理环境和场景变量
This commit is contained in:
parent
f6fcfe98ca
commit
d2dd6e5829
|
@ -82,7 +82,6 @@ public class ApiTestController {
|
|||
@RequiresPermissions(value = {
|
||||
PermissionConstants.PROJECT_API_DEFINITION_READ,
|
||||
PermissionConstants.PROJECT_API_DEFINITION_CASE_READ,
|
||||
PermissionConstants.PROJECT_API_DEBUG_READ,
|
||||
PermissionConstants.PROJECT_API_SCENARIO_READ
|
||||
}, logical = Logical.OR)
|
||||
public List<Environment> getEnvList(@PathVariable String projectId) {
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package io.metersphere.api.parser.jmeter;
|
||||
|
||||
import io.metersphere.jmeter.mock.Mock;
|
||||
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Argument;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL;
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-03-05 21:06
|
||||
*/
|
||||
public class JmeterTestElementParserHelper {
|
||||
|
||||
public static Arguments getArguments(String name) {
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(name + "_Arguments");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL));
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static Arguments getArguments(String name, List<CommonVariables> argumentList) {
|
||||
Arguments arguments = getArguments(name);
|
||||
parse2ArgumentList(argumentList).forEach(arguments::addArgument);
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public static List<Argument> parse2ArgumentList(List<CommonVariables> variables) {
|
||||
List<Argument> arguments = new ArrayList<>(variables.size());
|
||||
variables.forEach(variable -> {
|
||||
if (BooleanUtils.isFalse(variable.getEnable())) {
|
||||
return;
|
||||
}
|
||||
if (variable.isConstantValid()) {
|
||||
// 处理常量
|
||||
String value = StringUtils.isBlank(variable.getValue()) ? variable.getValue()
|
||||
: Mock.buildFunctionCallString(variable.getValue()).replaceAll("[\r\n]", "");
|
||||
arguments.add(new Argument(variable.getKey(), value, "="));
|
||||
} else if (variable.isListValid()) {
|
||||
// 处理 List 变量
|
||||
String[] arrays = variable.getValue().replaceAll("[\r\n]", "").split(",");
|
||||
for (int i = 0; i < arrays.length; i++) {
|
||||
arguments.add(new Argument(variable.getKey() + "_" + (i + 1), arrays[i], "="));
|
||||
}
|
||||
}
|
||||
});
|
||||
return arguments;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -25,11 +25,13 @@ import io.metersphere.project.dto.environment.GlobalParams;
|
|||
import io.metersphere.project.dto.environment.http.HttpConfig;
|
||||
import io.metersphere.project.dto.environment.http.HttpConfigPathMatchRule;
|
||||
import io.metersphere.project.dto.environment.http.SelectModule;
|
||||
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||
import io.metersphere.sdk.util.EnumValidator;
|
||||
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 org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.protocol.http.control.AuthManager;
|
||||
import org.apache.jmeter.protocol.http.control.Authorization;
|
||||
import org.apache.jmeter.protocol.http.control.Header;
|
||||
|
@ -68,6 +70,7 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
|
||||
ApiParamConfig apiParamConfig = (ApiParamConfig) config;
|
||||
HttpConfig httpConfig = getHttpConfig(msHTTPElement, apiParamConfig);
|
||||
EnvironmentInfoDTO envConfig = apiParamConfig.getEnvConfig(msHTTPElement.getProjectId());
|
||||
|
||||
HTTPSamplerProxy sampler = new HTTPSamplerProxy();
|
||||
sampler.setName(msHTTPElement.getName());
|
||||
|
@ -87,19 +90,19 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
|
||||
HashTree httpTree = tree.add(sampler);
|
||||
|
||||
// 处理环境变量
|
||||
Arguments envArguments = getEnvArguments(msHTTPElement, envConfig);
|
||||
Optional.ofNullable(envArguments).ifPresent(httpTree::add);
|
||||
|
||||
// 处理请求头
|
||||
HeaderManager httpHeader = getHttpHeader(msHTTPElement, apiParamConfig, httpConfig);
|
||||
if (httpHeader != null) {
|
||||
httpTree.add(httpHeader);
|
||||
}
|
||||
Optional.ofNullable(httpHeader).ifPresent(httpTree::add);
|
||||
|
||||
HTTPAuthConfig authConfig = msHTTPElement.getAuthConfig();
|
||||
|
||||
// 处理认证信息
|
||||
AuthManager authManager = getAuthManager(authConfig);
|
||||
if (authManager != null) {
|
||||
httpTree.add(authManager);
|
||||
}
|
||||
Optional.ofNullable(authManager).ifPresent(httpTree::add);
|
||||
|
||||
parseChild(httpTree, msHTTPElement, config);
|
||||
}
|
||||
|
@ -160,6 +163,24 @@ public class MsHTTPElementConverter extends AbstractJmeterElementConverter<MsHTT
|
|||
return authManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加场景和环境变量
|
||||
* @param msHTTPElement
|
||||
* @param envInfo
|
||||
*/
|
||||
private Arguments getEnvArguments(MsHTTPElement msHTTPElement, EnvironmentInfoDTO envInfo) {
|
||||
if (envInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<CommonVariables> envVariables = envInfo.getConfig().getCommonVariables();
|
||||
if (CollectionUtils.isEmpty(envVariables)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return JmeterTestElementParserHelper.getArguments(msHTTPElement.getName(), envVariables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置步骤标识
|
||||
* 当前步骤唯一标识,结果和步骤匹配的关键
|
||||
|
|
|
@ -7,6 +7,7 @@ import io.metersphere.api.dto.request.MsScenario;
|
|||
import io.metersphere.api.dto.request.processors.MsProcessorConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioStepConfig;
|
||||
import io.metersphere.api.dto.scenario.ScenarioVariable;
|
||||
import io.metersphere.api.parser.jmeter.processor.MsProcessorConverter;
|
||||
import io.metersphere.api.parser.jmeter.processor.MsProcessorConverterFactory;
|
||||
import io.metersphere.api.parser.jmeter.processor.assertion.AssertionConverterFactory;
|
||||
|
@ -17,10 +18,12 @@ import io.metersphere.project.api.processor.MsProcessor;
|
|||
import io.metersphere.project.dto.environment.EnvironmentConfig;
|
||||
import io.metersphere.project.dto.environment.EnvironmentInfoDTO;
|
||||
import io.metersphere.project.dto.environment.processors.EnvProcessorConfig;
|
||||
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.protocol.http.control.CookieManager;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
|
@ -29,6 +32,8 @@ import org.apache.jorphan.collections.HashTree;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.COOKIE_PANEL;
|
||||
|
||||
|
@ -50,6 +55,9 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
tree.add(getCookieManager());
|
||||
}
|
||||
|
||||
// 添加场景和环境变量
|
||||
addArguments(tree, msScenario, envInfo);
|
||||
|
||||
// 添加环境的前置
|
||||
addEnvScenarioProcessor(tree, msScenario, config, envInfo, true);
|
||||
// 添加场景前置
|
||||
|
@ -68,6 +76,72 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
addScenarioAssertions(tree, msScenario, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加场景和环境变量
|
||||
* @param tree
|
||||
* @param msScenario
|
||||
* @param envInfo
|
||||
*/
|
||||
private void addArguments(HashTree tree, MsScenario msScenario, EnvironmentInfoDTO envInfo) {
|
||||
|
||||
ScenarioConfig scenarioConfig = msScenario.getScenarioConfig();
|
||||
ScenarioVariable scenarioVariable = scenarioConfig == null ? new ScenarioVariable() : scenarioConfig.getVariable();
|
||||
List<CommonVariables> commonVariables = scenarioVariable.getCommonVariables();
|
||||
|
||||
List<CommonVariables> envCommonVariables = List.of();
|
||||
if (needParseEnv(msScenario) && envInfo.getConfig() != null) {
|
||||
// 获取环境变量
|
||||
envCommonVariables = envInfo.getConfig().getCommonVariables();
|
||||
// 获取后,将环境变量置空,避免请求重复设置
|
||||
envInfo.getConfig().setCommonVariables(List.of());
|
||||
}
|
||||
|
||||
List<CommonVariables> constantVariables = mergeEnvVariables(commonVariables, envCommonVariables, CommonVariables::isConstantValid);
|
||||
List<CommonVariables> listVariables = mergeEnvVariables(commonVariables, envCommonVariables, CommonVariables::isListValid);
|
||||
|
||||
if (CollectionUtils.isEmpty(commonVariables) && CollectionUtils.isEmpty(envCommonVariables)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Arguments arguments = JmeterTestElementParserHelper.getArguments(msScenario.getName());
|
||||
JmeterTestElementParserHelper.parse2ArgumentList(constantVariables).forEach(arguments::addArgument);
|
||||
JmeterTestElementParserHelper.parse2ArgumentList(listVariables).forEach(arguments::addArgument);
|
||||
tree.add(arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并环境变量和场景变量
|
||||
* @param scenarioVariables
|
||||
* @param envCommonVariables
|
||||
* @param filter
|
||||
* @return
|
||||
*/
|
||||
private List<CommonVariables> mergeEnvVariables(List<CommonVariables> scenarioVariables, List<CommonVariables> envCommonVariables, Predicate<CommonVariables> filter) {
|
||||
List<CommonVariables> variables = scenarioVariables
|
||||
.stream()
|
||||
.filter(CommonVariables::getEnable)
|
||||
.filter(filter::test)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<CommonVariables> envConstantVariables = envCommonVariables
|
||||
.stream()
|
||||
.filter(CommonVariables::getEnable)
|
||||
.filter(filter::test)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<String, String> scenarioVariableMap = variables
|
||||
.stream()
|
||||
.collect(Collectors.toMap(CommonVariables::getKey, CommonVariables::getValue));
|
||||
|
||||
for (CommonVariables globalConstantVariable : envConstantVariables) {
|
||||
String key = globalConstantVariable.getKey();
|
||||
if (!scenarioVariableMap.containsKey(key)) {
|
||||
variables.add(globalConstantVariable);
|
||||
}
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加场景断言
|
||||
*
|
||||
|
@ -105,18 +179,8 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
EnvironmentInfoDTO envInfo,
|
||||
boolean isPre) {
|
||||
|
||||
if (isRef(msScenario.getRefType())) {
|
||||
ScenarioStepConfig scenarioStepConfig = msScenario.getScenarioStepConfig();
|
||||
if (scenarioStepConfig == null || BooleanUtils.isFalse(scenarioStepConfig.getEnableScenarioEnv())) {
|
||||
// 引用的场景,如果没有开启源场景环境,不添加环境的前后置
|
||||
return;
|
||||
}
|
||||
} else if (isCopy(msScenario.getRefType())) {
|
||||
// 复制场景,不添加环境的前后置
|
||||
if (!needParseEnv(msScenario)) {
|
||||
return;
|
||||
} else {
|
||||
// 当前场景,添加环境的前后置
|
||||
// do nothing
|
||||
}
|
||||
|
||||
ScenarioConfig scenarioConfig = msScenario.getScenarioConfig();
|
||||
|
@ -147,6 +211,28 @@ public class MsScenarioConverter extends AbstractJmeterElementConverter<MsScenar
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要解析环境
|
||||
* @param msScenario
|
||||
* @return
|
||||
*/
|
||||
private boolean needParseEnv(MsScenario msScenario) {
|
||||
if (isRef(msScenario.getRefType())) {
|
||||
ScenarioStepConfig scenarioStepConfig = msScenario.getScenarioStepConfig();
|
||||
if (scenarioStepConfig == null || BooleanUtils.isFalse(scenarioStepConfig.getEnableScenarioEnv())) {
|
||||
// 引用的场景,如果没有开启源场景环境,不解析环境
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else if (isCopy(msScenario.getRefType())) {
|
||||
// 复制场景,不解析环境
|
||||
return false;
|
||||
} else {
|
||||
// 当前场景,解析环境
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void addScenarioProcessor(HashTree tree, MsScenario msScenario, ParameterConfig config, boolean isPre) {
|
||||
if (isCopy(msScenario.getRefType())) {
|
||||
// 复制的场景,没有前后置
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package io.metersphere.api.parser.jmeter.processor;
|
||||
|
||||
import io.metersphere.api.parser.jmeter.JmeterTestElementParserHelper;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||
import io.metersphere.api.parser.jmeter.constants.JmeterProperty;
|
||||
import io.metersphere.plugin.api.constants.ElementProperty;
|
||||
|
@ -15,8 +16,6 @@ import org.apache.jmeter.testelement.TestElement;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: jianxing
|
||||
|
@ -79,11 +78,7 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter<Scri
|
|||
return null;
|
||||
}
|
||||
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(scriptProcessor.getName() + "_Arguments");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL));
|
||||
Arguments arguments = JmeterTestElementParserHelper.getArguments(scriptProcessor.getName());
|
||||
for (KeyValueParam param : params) {
|
||||
arguments.addArgument(param.getKey(), param.getValue(), "=");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.api.parser.jmeter.processor;
|
||||
|
||||
import io.metersphere.api.dto.ApiParamConfig;
|
||||
import io.metersphere.api.parser.jmeter.JmeterTestElementParserHelper;
|
||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||
import io.metersphere.project.api.KeyValueParam;
|
||||
import io.metersphere.project.api.processor.SQLProcessor;
|
||||
|
@ -18,7 +19,6 @@ import org.apache.jorphan.collections.HashTree;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.ARGUMENTS_PANEL;
|
||||
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.TEST_BEAN_GUI;
|
||||
|
||||
|
||||
|
@ -68,12 +68,7 @@ public abstract class SqlProcessorConverter extends MsProcessorConverter<SQLProc
|
|||
|
||||
public Arguments getJdbcArguments(String name, List<KeyValueParam> extractParams) {
|
||||
if (CollectionUtils.isNotEmpty(extractParams)) {
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.setEnabled(true);
|
||||
name = StringUtils.isNotEmpty(name) ? name : "Arguments";
|
||||
arguments.setName(name + "_JDBC_Argument");
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
arguments.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(ARGUMENTS_PANEL));
|
||||
Arguments arguments = JmeterTestElementParserHelper.getArguments(name);
|
||||
extractParams.stream().filter(KeyValueParam::isValid)
|
||||
.forEach(keyValue ->
|
||||
arguments.addArgument(keyValue.getKey(), String.format("vars.get(\"%s\")", keyValue.getValue()), "=")
|
||||
|
|
|
@ -45,6 +45,7 @@ import io.metersphere.project.dto.environment.http.SelectModule;
|
|||
import io.metersphere.project.dto.environment.processors.EnvProcessorConfig;
|
||||
import io.metersphere.project.dto.environment.processors.EnvRequestScriptProcessor;
|
||||
import io.metersphere.project.dto.environment.processors.EnvScenarioScriptProcessor;
|
||||
import io.metersphere.project.dto.environment.variables.CommonVariables;
|
||||
import io.metersphere.project.dto.filemanagement.request.FileUploadRequest;
|
||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||
import io.metersphere.project.mapper.ProjectVersionMapper;
|
||||
|
@ -760,6 +761,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
request.getStepDetails().put(pluginStep.getId(), pluginStepDetail);
|
||||
request.getScenarioConfig().getOtherConfig().setEnableCookieShare(true);
|
||||
request.getScenarioConfig().getOtherConfig().setEnableGlobalCookie(false);
|
||||
request.getScenarioConfig().setVariable(getScenarioVariable());
|
||||
|
||||
Plugin plugin = addEnvTestPlugin();
|
||||
this.requestPostWithOk(DEBUG, request);
|
||||
|
@ -769,6 +771,24 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE, DEBUG, request);
|
||||
}
|
||||
|
||||
private ScenarioVariable getScenarioVariable() {
|
||||
ScenarioVariable scenarioVariable = new ScenarioVariable();
|
||||
CommonVariables commonVariables1 = new CommonVariables();
|
||||
commonVariables1.setType(VariableTypeConstants.CONSTANT.name());
|
||||
commonVariables1.setKey("a");
|
||||
commonVariables1.setValue("b");
|
||||
CommonVariables commonVariables2 = new CommonVariables();
|
||||
commonVariables2.setType(VariableTypeConstants.CONSTANT.name());
|
||||
commonVariables2.setKey("b");
|
||||
commonVariables2.setValue("c");
|
||||
CommonVariables commonVariables3 = new CommonVariables();
|
||||
commonVariables3.setType(VariableTypeConstants.LIST.name());
|
||||
commonVariables3.setKey("list1");
|
||||
commonVariables3.setValue("1,2,3");
|
||||
scenarioVariable.setCommonVariables(List.of(commonVariables1, commonVariables2, commonVariables3));
|
||||
return scenarioVariable;
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void testTransfer() throws Exception {
|
||||
|
@ -1051,6 +1071,20 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
DataSource dataSource = getDataSource();
|
||||
environmentConfig.setDataSources(List.of(dataSource));
|
||||
|
||||
CommonVariables commonVariables1 = new CommonVariables();
|
||||
commonVariables1.setType(VariableTypeConstants.CONSTANT.name());
|
||||
commonVariables1.setKey("a");
|
||||
commonVariables1.setValue("c");
|
||||
CommonVariables commonVariables2 = new CommonVariables();
|
||||
commonVariables2.setType(VariableTypeConstants.CONSTANT.name());
|
||||
commonVariables2.setKey("q");
|
||||
commonVariables2.setValue("qq");
|
||||
CommonVariables commonVariables3 = new CommonVariables();
|
||||
commonVariables3.setType(VariableTypeConstants.LIST.name());
|
||||
commonVariables3.setKey("list1");
|
||||
commonVariables3.setValue("1,2,3,5");
|
||||
environmentConfig.setCommonVariables(List.of(commonVariables1, commonVariables2, commonVariables3));
|
||||
|
||||
EnvProcessorConfig preProcessorConfig = environmentConfig.getPreProcessorConfig();
|
||||
EnvProcessorConfig postProcessorConfig = environmentConfig.getPostProcessorConfig();
|
||||
List<MsProcessor> preProcessors = preProcessorConfig.getApiProcessorConfig().getScenarioProcessorConfig().getProcessors();
|
||||
|
|
Loading…
Reference in New Issue