feat(接口测试): 场景脚本步骤

This commit is contained in:
AgAngle 2024-03-23 17:53:37 +08:00 committed by Craftsman
parent ca5478bcf3
commit 1b95d82b6a
11 changed files with 108 additions and 125 deletions

View File

@ -39,5 +39,8 @@ public enum ApiScenarioStepType {
* 等待控制器
*/
CONSTANT_TIMER,
/**
* 脚本操作
*/
SCRIPT,
}

View File

@ -1,29 +0,0 @@
package io.metersphere.api.dto.request.controller;
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.api.KeyValueParam;
import lombok.Data;
import java.util.List;
/**
* 公共脚本组件
* 主要用于公共脚本测试执行时生成jmx
*/
@Data
public class MsCommentScriptElement extends AbstractMsTestElement {
/**
* 脚本内容
*/
private String script;
/**
* 脚本语言
* @see io.metersphere.project.constants.ScriptLanguageType
*/
private String scriptLanguage;
/**
* 公共脚本入参
*/
private List<KeyValueParam> params;
}

View File

@ -0,0 +1,43 @@
package io.metersphere.api.dto.request.controller;
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.constants.ScriptLanguageType;
import io.metersphere.project.dto.CommonScriptInfo;
import io.metersphere.system.valid.EnumValue;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
/**
* 公共脚本组件
* 主要用于公共脚本测试执行时生成jmx
*/
@Data
public class MsScriptElement extends AbstractMsTestElement {
/**
* 脚本内容
*/
private String script;
/**
* 脚本语言
* {@link ScriptLanguageType}
*/
@Size(max = 20)
@NotBlank
@EnumValue(enumClass = ScriptLanguageType.class)
private String scriptLanguage;
/**
* 是否启用公共脚本
* 默认为 false
* 环境脚本无须配置
*/
private Boolean enableCommonScript = false;
/**
* 公共脚本信息
* {@link CommonScriptInfo}
*/
@Valid
private CommonScriptInfo commonScriptInfo;
}

View File

@ -50,8 +50,8 @@ public class ApiScenarioAddRequest {
@Schema(description = "标签")
private List<String> tags;
@Schema(description = "是否为环境组", requiredMode = Schema.RequiredMode.REQUIRED)
private Boolean grouped;
@Schema(description = "是否为环境组")
private Boolean grouped = false;
@Schema(description = "环境或者环境组ID")
@Size(max = 50, message = "{api_scenario.environment_id.length_range}")

View File

@ -8,4 +8,10 @@ import lombok.Data;
*/
@Data
public class ApiScenarioStepRequest extends ApiScenarioStepCommonDTO {
/**
* 记录是从哪个步骤复制来的
* 如果没有传步骤详情
* 保存时需要根据这个字段查询原步骤详情保存
*/
private String copyFromStepId;
}

View File

@ -16,11 +16,15 @@ public class ScenarioOtherConfig {
* 是否共享cookie
*/
private Boolean enableCookieShare = false;
/**
* 启用场景步骤等待时间
*/
private Boolean enableStepWait = false;
/**
* 场景步骤等待时间
* 每一个步骤执行后都会等待相应的时间
*/
private Integer stepWaitTime;
private Long stepWaitTime;
/**
* 失败策略
* @see FailureStrategy

View File

@ -1,86 +0,0 @@
package io.metersphere.api.parser.jmeter;
import io.metersphere.api.dto.request.controller.MsCommentScriptElement;
import io.metersphere.project.api.KeyValueParam;
import io.metersphere.project.api.processor.ScriptProcessor;
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.jmeter.modifiers.UserParameters;
import org.apache.jmeter.protocol.java.sampler.BeanShellSampler;
import org.apache.jmeter.protocol.java.sampler.JSR223Sampler;
import org.apache.jmeter.save.SaveService;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.USER_PARAMETERS_GUI;
/**
* @Author: jianxing
* @CreateTime: 2024-01-18 22:04
*/
public class MsCommentScriptElementConverter extends AbstractJmeterElementConverter<MsCommentScriptElement> {
@Override
public void toHashTree(HashTree hashTree, MsCommentScriptElement msElement, ParameterConfig config) {
if (CollectionUtils.isNotEmpty(msElement.getParams())) {
// 添加变量
List<KeyValueParam> params = msElement.getParams()
.stream()
.filter(KeyValueParam::isValid)
.collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(params)) {
UserParameters userParameters = getUserParameters(params);
hashTree.add(userParameters);
}
}
// 添加脚本
ScriptProcessor scriptProcessor = new ScriptProcessor();
scriptProcessor.setScriptLanguage(msElement.getScriptLanguage());
scriptProcessor.setScript(msElement.getScript());
TestElement scriptElement;
if (ScriptProcessorConverter.isJSR233(scriptProcessor)) {
scriptElement = new JSR223Sampler();
} else {
scriptElement = new BeanShellSampler();
}
ScriptProcessorConverter.parse(scriptElement, scriptProcessor, config);
// 添加公共脚本的参数
Optional.ofNullable(ScriptProcessorConverter.getScriptArguments(scriptProcessor))
.ifPresent(hashTree::add);
hashTree.add(scriptElement);
}
public static UserParameters getUserParameters(List<KeyValueParam> params) {
UserParameters processor = new UserParameters();
processor.setEnabled(true);
processor.setName("User Defined Variables");
processor.setPerIteration(true);
processor.setProperty(TestElement.TEST_CLASS, UserParameters.class.getName());
processor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(USER_PARAMETERS_GUI));
if (CollectionUtils.isNotEmpty(params)) {
List<String> names = new LinkedList<>();
List<Object> values = new LinkedList<>();
List<Object> threadValues = new LinkedList<>();
for (KeyValueParam param : params) {
String name = param.getKey();
String value = param.getValue();
names.add(name);
values.add(value);
}
processor.setNames(names);
threadValues.add(values);
processor.setThreadLists(threadValues);
}
return processor;
}
}

View File

@ -0,0 +1,34 @@
package io.metersphere.api.parser.jmeter;
import io.metersphere.api.dto.request.controller.MsScriptElement;
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
import io.metersphere.project.api.processor.ScriptProcessor;
import io.metersphere.sdk.util.BeanUtils;
import org.apache.jmeter.protocol.java.sampler.BeanShellSampler;
import org.apache.jmeter.protocol.java.sampler.JSR223Sampler;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.collections.HashTree;
/**
* @Author: jianxing
* @CreateTime: 2024-01-18 22:04
*/
public class MsScriptElementConverter extends AbstractJmeterElementConverter<MsScriptElement> {
@Override
public void toHashTree(HashTree hashTree, MsScriptElement msScriptElement, ParameterConfig config) {
// 添加脚本
ScriptProcessor scriptProcessor = BeanUtils.copyBean(new ScriptProcessor(), msScriptElement);
TestElement scriptElement;
if (ScriptProcessorConverter.isJSR233(scriptProcessor)) {
scriptElement = new JSR223Sampler();
} else {
scriptElement = new BeanShellSampler();
}
ScriptProcessorConverter.parse(scriptElement, scriptProcessor, config);
hashTree.add(scriptElement);
}
}

View File

@ -6,7 +6,7 @@ import io.metersphere.api.controller.result.ApiResultCode;
import io.metersphere.api.dto.ApiParamConfig;
import io.metersphere.api.dto.debug.ApiDebugRunRequest;
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
import io.metersphere.api.dto.request.controller.MsCommentScriptElement;
import io.metersphere.api.dto.request.controller.MsScriptElement;
import io.metersphere.api.parser.TestElementParser;
import io.metersphere.api.parser.TestElementParserFactory;
import io.metersphere.api.utils.ApiDataUtils;
@ -14,6 +14,7 @@ import io.metersphere.plugin.api.dto.ParameterConfig;
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
import io.metersphere.project.domain.FileMetadata;
import io.metersphere.project.domain.ProjectApplication;
import io.metersphere.project.dto.CommonScriptInfo;
import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest;
import io.metersphere.project.dto.environment.GlobalParams;
import io.metersphere.project.dto.environment.GlobalParamsDTO;
@ -251,11 +252,18 @@ public class ApiExecuteService {
String testId = runRequest.getProjectId();
// 生成执行脚本
MsCommentScriptElement msCommentScriptElement = BeanUtils.copyBean(new MsCommentScriptElement(), runRequest);
msCommentScriptElement.setScriptLanguage(runRequest.getType());
MsScriptElement msScriptElement = new MsScriptElement();
msScriptElement.setEnableCommonScript(true);
msScriptElement.setName(runRequest.getReportId());
CommonScriptInfo commonScriptInfo = new CommonScriptInfo();
commonScriptInfo.setParams(runRequest.getParams());
commonScriptInfo.setScript(runRequest.getScript());
commonScriptInfo.setScriptLanguage(runRequest.getType());
commonScriptInfo.setName(runRequest.getReportId());
msScriptElement.setCommonScriptInfo(commonScriptInfo);
ApiResourceRunRequest apiRunRequest = new ApiResourceRunRequest();
apiRunRequest.setTestElement(msCommentScriptElement);
apiRunRequest.setTestElement(msScriptElement);
// 设置执行参数
TaskRequestDTO taskRequest = getTaskRequest(reportId, testId, runRequest.getProjectId());

View File

@ -27,7 +27,7 @@ public class JmeterElementConverterRegister {
// 注册默认的转换器 todo 注册插件的转换器
register(MsHTTPElementConverter.class);
register(MsCommonElementConverter.class);
register(MsCommentScriptElementConverter.class);
register(MsScriptElementConverter.class);
register(MsScenarioConverter.class);
register(MsIfControllerConverter.class);
register(MsLoopControllerConverter.class);

View File

@ -427,7 +427,7 @@ public class ApiScenarioControllerTests extends BaseTest {
responseCodeAssertion.setName("test");
scenarioConfig.getAssertionConfig().getAssertions().add(responseCodeAssertion);
ScenarioOtherConfig scenarioOtherConfig = new ScenarioOtherConfig();
scenarioOtherConfig.setStepWaitTime(1000);
scenarioOtherConfig.setStepWaitTime(1000L);
scenarioOtherConfig.setFailureStrategy(ScenarioOtherConfig.FailureStrategy.CONTINUE.name());
scenarioOtherConfig.setEnableCookieShare(true);
scenarioConfig.setOtherConfig(scenarioOtherConfig);