feat(接口测试): 获取场景步骤详情接口
This commit is contained in:
parent
478e119a2c
commit
b5dca1b323
|
@ -380,6 +380,7 @@ schedule_not_exist=定时任务不存在
|
|||
api_case_report_not_exist=用例报告不存在
|
||||
api_scenario_report_not_exist=场景报告不存在
|
||||
permission.api_plugin.name=接口插件
|
||||
permission.api_step.name=步骤
|
||||
|
||||
#module:ApiScenarioCsv
|
||||
api_scenario_csv.file_id.not_blank=文件ID不能为空
|
||||
|
@ -398,4 +399,3 @@ api_scenario_csv.ignore_first_line.not_blank=是否忽略第一行
|
|||
api_scenario_csv.allow_quoted_data.not_blank=是否允许带引号
|
||||
api_scenario_csv.recycle_on_eof.not_blank=是否循环
|
||||
api_scenario_csv.stop_thread_on_eof.not_blank=是否停止线程
|
||||
|
||||
|
|
|
@ -392,6 +392,7 @@ schedule_not_exist=The scheduled task does not exist
|
|||
api_case_report_not_exist=Api report does not exist
|
||||
api_scenario_report_not_exist=Scenario report does not exist
|
||||
permission.api_plugin.name=Api Plugin
|
||||
permission.api_step.name=Step
|
||||
|
||||
#module:ApiScenarioCsv
|
||||
api_scenario_csv.file_id.not_blank=File ID cannot be empty
|
||||
|
|
|
@ -361,6 +361,7 @@ schedule_not_exist=定时任务不存在
|
|||
api_case_report_not_exist=用例报告不存在
|
||||
api_scenario_report_not_exist=场景报告不存在
|
||||
permission.api_plugin.name=接口插件
|
||||
permission.api_step.name=步骤
|
||||
|
||||
#module:ApiScenarioCsv
|
||||
api_scenario_csv.file_id.not_blank=文件ID不能为空
|
||||
|
|
|
@ -361,6 +361,7 @@ schedule_not_exist=定時任務不存在
|
|||
api_case_report_not_exist=用例報告不存在
|
||||
api_scenario_report_not_exist=場景報告不存在
|
||||
permission.api_plugin.name=接口插件
|
||||
permission.api_step.name=步驟
|
||||
|
||||
#module:ApiScenarioCsv 繁体
|
||||
api_scenario_csv.file_id.not_blank=文件ID不能為空
|
||||
|
|
|
@ -114,10 +114,18 @@ public class ApiScenarioController {
|
|||
@GetMapping("/get/{scenarioId}")
|
||||
@Operation(summary = "接口测试-接口场景管理-获取场景详情")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ)
|
||||
@CheckOwner(resourceId = "#scenarioId", resourceType = "api_scenario")
|
||||
public ApiScenarioDetail get(@PathVariable String scenarioId) {
|
||||
return apiScenarioService.get(scenarioId);
|
||||
}
|
||||
|
||||
@GetMapping("/step/get/{stepId}")
|
||||
@Operation(summary = "接口测试-接口场景管理-获取场景步骤详情")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_READ)
|
||||
public Object getStepDetail(@PathVariable String stepId) {
|
||||
return apiScenarioService.getStepDetail(stepId);
|
||||
}
|
||||
|
||||
@PostMapping("/debug")
|
||||
@Operation(summary = "接口测试-接口场景管理-场景调试")
|
||||
@RequiresPermissions(PermissionConstants.PROJECT_API_SCENARIO_EXECUTE)
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
package io.metersphere.api.parser.step;
|
||||
|
||||
import io.metersphere.api.domain.ApiScenarioStep;
|
||||
import io.metersphere.api.domain.ApiTestCaseBlob;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
|
||||
import io.metersphere.api.mapper.ApiTestCaseBlobMapper;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -11,7 +15,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
*/
|
||||
public class ApiCaseStepParser extends StepParser {
|
||||
@Override
|
||||
public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
if (isRef(step.getRefType())) {
|
||||
return StringUtils.isBlank(resourceBlob) ? null : parse2MsTestElement(resourceBlob);
|
||||
} else {
|
||||
|
@ -21,4 +25,18 @@ public class ApiCaseStepParser extends StepParser {
|
|||
return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseDetail(ApiScenarioStep step) {
|
||||
if (isRef(step.getRefType())) {
|
||||
ApiTestCaseBlobMapper apiTestCaseBlobMapper = CommonBeanFactory.getBean(ApiTestCaseBlobMapper.class);
|
||||
ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(step.getResourceId());
|
||||
if (apiTestCaseBlob == null) {
|
||||
return null;
|
||||
}
|
||||
return parse2MsTestElement(new String(apiTestCaseBlob.getRequest()));
|
||||
} else {
|
||||
return parse2MsTestElement(getStepBlobString(step.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
package io.metersphere.api.parser.step;
|
||||
|
||||
import io.metersphere.api.domain.ApiScenarioBlob;
|
||||
import io.metersphere.api.domain.ApiScenarioStep;
|
||||
import io.metersphere.api.dto.request.MsScenario;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
|
||||
import io.metersphere.api.dto.scenario.ScenarioConfig;
|
||||
import io.metersphere.api.mapper.ApiScenarioBlobMapper;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -13,7 +17,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
*/
|
||||
public class ApiScenarioStepParser extends StepParser {
|
||||
@Override
|
||||
public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
MsScenario msScenario = new MsScenario();
|
||||
if (isRef(step.getRefType())) {
|
||||
if (StringUtils.isNotBlank(resourceBlob)) {
|
||||
|
@ -26,4 +30,27 @@ public class ApiScenarioStepParser extends StepParser {
|
|||
}
|
||||
return msScenario;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取场景配置详情
|
||||
* @param step
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Object parseDetail(ApiScenarioStep step) {
|
||||
if (isRef(step.getRefType())) {
|
||||
ApiScenarioBlobMapper apiScenarioBlobMapper = CommonBeanFactory.getBean(ApiScenarioBlobMapper.class);
|
||||
ApiScenarioBlob apiScenarioBlob = apiScenarioBlobMapper.selectByPrimaryKey(step.getResourceId());
|
||||
if (apiScenarioBlob == null || apiScenarioBlob.getConfig() == null) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(new String(apiScenarioBlob.getConfig()), ScenarioConfig.class);
|
||||
} else {
|
||||
String stepDetailStr= getStepBlobString(step.getId());
|
||||
if (StringUtils.isBlank(stepDetailStr)) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parseObject(stepDetailStr, ScenarioConfig.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package io.metersphere.api.parser.step;
|
||||
|
||||
import io.metersphere.api.domain.ApiDefinitionBlob;
|
||||
import io.metersphere.api.domain.ApiScenarioStep;
|
||||
import io.metersphere.api.dto.request.http.KeyValueParam;
|
||||
import io.metersphere.api.dto.request.http.MsHTTPElement;
|
||||
import io.metersphere.api.dto.request.http.body.Body;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
|
||||
import io.metersphere.api.mapper.ApiDefinitionBlobMapper;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
@ -17,22 +21,48 @@ import java.util.List;
|
|||
*/
|
||||
public class ApiStepParser extends StepParser {
|
||||
@Override
|
||||
public AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
if (isRef(step.getRefType())) {
|
||||
return parseRefTestElement(resourceBlob, stepDetail);
|
||||
} else {
|
||||
return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理引用的接口步骤
|
||||
* 替换修改的参数
|
||||
* @param resourceBlob 引用的接口步骤详情
|
||||
* @param stepDetail 引用之后修改的步骤详情
|
||||
* @return
|
||||
*/
|
||||
public AbstractMsTestElement parseRefTestElement(String resourceBlob, String stepDetail) {
|
||||
if (StringUtils.isBlank(resourceBlob)) {
|
||||
return null;
|
||||
}
|
||||
AbstractMsTestElement refResourceElement = parse2MsTestElement(resourceBlob);
|
||||
if (refResourceElement instanceof MsHTTPElement && StringUtils.isNotBlank(stepDetail)) {
|
||||
// 如果是 http 并且有修改请求参数,则替换请求参数
|
||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||
return replaceParams((MsHTTPElement) msTestElement, (MsHTTPElement) refResourceElement);
|
||||
AbstractMsTestElement stepElement = parse2MsTestElement(stepDetail);
|
||||
return replaceParams((MsHTTPElement) stepElement, (MsHTTPElement) refResourceElement);
|
||||
} else {
|
||||
return refResourceElement;
|
||||
}
|
||||
} else {
|
||||
return StringUtils.isBlank(stepDetail) ? null : ApiDataUtils.parseObject(stepDetail, AbstractMsTestElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseDetail(ApiScenarioStep step) {
|
||||
if (isRef(step.getRefType())) {
|
||||
ApiDefinitionBlobMapper apiDefinitionBlobMapper = CommonBeanFactory.getBean(ApiDefinitionBlobMapper.class);
|
||||
ApiDefinitionBlob apiDefinitionBlob = apiDefinitionBlobMapper.selectByPrimaryKey(step.getResourceId());
|
||||
if (apiDefinitionBlob == null) {
|
||||
return null;
|
||||
}
|
||||
return parseRefTestElement(new String(apiDefinitionBlob.getRequest()), getStepBlobString(step.getId()));
|
||||
} else {
|
||||
return parse2MsTestElement(getStepBlobString(step.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package io.metersphere.api.parser.step;
|
||||
|
||||
import io.metersphere.api.domain.ApiScenarioStep;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
|
||||
/**
|
||||
* 默认的步骤解析器
|
||||
* 逻辑控制器等步骤,直接将步骤详情解析为 MsTestElement
|
||||
* @Author: jianxing
|
||||
* @CreateTime: 2024-01-20 15:43
|
||||
*/
|
||||
public class DefaultStepParser extends StepParser {
|
||||
|
||||
@Override
|
||||
public AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail) {
|
||||
return parse2MsTestElement(stepDetail);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object parseDetail(ApiScenarioStep step) {
|
||||
return parse2MsTestElement(getStepBlobString(step.getId()));
|
||||
}
|
||||
}
|
|
@ -1,10 +1,13 @@
|
|||
package io.metersphere.api.parser.step;
|
||||
|
||||
import io.metersphere.api.constants.ApiScenarioStepRefType;
|
||||
import io.metersphere.api.domain.ApiScenarioStep;
|
||||
import io.metersphere.api.domain.ApiScenarioStepBlob;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepCommonDTO;
|
||||
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
|
||||
import io.metersphere.api.mapper.ApiScenarioStepBlobMapper;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||
import io.metersphere.sdk.util.CommonBeanFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -13,13 +16,42 @@ import org.apache.commons.lang3.StringUtils;
|
|||
*/
|
||||
public abstract class StepParser {
|
||||
|
||||
public abstract AbstractMsTestElement parse(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail);
|
||||
/**
|
||||
* 将步骤详情解析为 MsTestElement
|
||||
* @param step 步骤
|
||||
* @param resourceBlob 关联的资源详情
|
||||
* @param stepDetail 步骤详情
|
||||
* @return
|
||||
*/
|
||||
public abstract AbstractMsTestElement parseTestElement(ApiScenarioStepCommonDTO step, String resourceBlob, String stepDetail);
|
||||
|
||||
/**
|
||||
* 将步骤解析为步骤详情
|
||||
* 场景步骤,返回 ScenarioConfig
|
||||
* 其余返回 MsTestElement
|
||||
* @param step
|
||||
* @return
|
||||
*/
|
||||
public abstract Object parseDetail(ApiScenarioStep step);
|
||||
|
||||
|
||||
protected boolean isRef(String refType) {
|
||||
return StringUtils.equalsAny(refType, ApiScenarioStepRefType.REF.name(), ApiScenarioStepRefType.PARTIAL_REF.name());
|
||||
}
|
||||
|
||||
protected static AbstractMsTestElement parse2MsTestElement(String blobContent) {
|
||||
if (StringUtils.isBlank(blobContent)) {
|
||||
return null;
|
||||
}
|
||||
return ApiDataUtils.parseObject(blobContent, AbstractMsTestElement.class);
|
||||
}
|
||||
|
||||
protected String getStepBlobString(String stepId) {
|
||||
ApiScenarioStepBlobMapper apiScenarioStepBlobMapper = CommonBeanFactory.getBean(ApiScenarioStepBlobMapper.class);
|
||||
ApiScenarioStepBlob apiScenarioStepBlob = apiScenarioStepBlobMapper.selectByPrimaryKey(stepId);
|
||||
if (apiScenarioStepBlob == null) {
|
||||
return null;
|
||||
}
|
||||
return new String(apiScenarioStepBlob.getContent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Map;
|
|||
public abstract class StepParserFactory {
|
||||
|
||||
private static Map<String, StepParser> stepParserMap = new HashMap<>();
|
||||
private static StepParser defaultStepParser = new DefaultStepParser();
|
||||
|
||||
static {
|
||||
stepParserMap.put(ApiScenarioStepType.API.name(), new ApiStepParser());
|
||||
|
@ -20,6 +21,7 @@ public abstract class StepParserFactory {
|
|||
}
|
||||
|
||||
public static StepParser getStepParser(String stepType) {
|
||||
return stepParserMap.get(stepType);
|
||||
StepParser stepParser = stepParserMap.get(stepType);
|
||||
return stepParser == null ? defaultStepParser : stepParser;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -908,13 +908,13 @@ public class ApiScenarioService {
|
|||
}
|
||||
for (ApiScenarioStepCommonDTO step : steps) {
|
||||
StepParser stepParser = StepParserFactory.getStepParser(step.getStepType());
|
||||
if (stepParser == null || BooleanUtils.isFalse(step.getEnable())) {
|
||||
if (BooleanUtils.isFalse(step.getEnable())) {
|
||||
continue;
|
||||
}
|
||||
setPartialRefStepEnable(step, stepDetailMap);
|
||||
|
||||
// 将步骤详情解析生成对应的MsTestElement
|
||||
AbstractMsTestElement msTestElement = stepParser.parse(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId()));
|
||||
AbstractMsTestElement msTestElement = stepParser.parseTestElement(step, resourceBlobMap.get(step.getResourceId()), stepDetailMap.get(step.getId()));
|
||||
if (msTestElement != null) {
|
||||
parentElement.getChildren().add(msTestElement);
|
||||
}
|
||||
|
@ -1261,4 +1261,14 @@ public class ApiScenarioService {
|
|||
}
|
||||
return extApiScenarioStepMapper.getStepDTOByScenarioIds(scenarioIds);
|
||||
}
|
||||
|
||||
public Object getStepDetail(String stepId) {
|
||||
ApiScenarioStep step = checkStepExist(stepId);
|
||||
StepParser stepParser = StepParserFactory.getStepParser(step.getStepType());
|
||||
return stepParser.parseDetail(step);
|
||||
}
|
||||
|
||||
private ApiScenarioStep checkStepExist(String id) {
|
||||
return ServiceUtils.checkResourceExist(apiScenarioStepMapper.selectByPrimaryKey(id), "permission.api_step.name");
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import io.metersphere.api.mapper.*;
|
|||
import io.metersphere.api.service.BaseResourcePoolTestService;
|
||||
import io.metersphere.api.service.definition.ApiDefinitionService;
|
||||
import io.metersphere.api.service.definition.ApiTestCaseService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.project.dto.filemanagement.request.FileUploadRequest;
|
||||
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
|
||||
|
@ -65,6 +66,7 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
private static final String FOLLOW = "follow/";
|
||||
protected static final String UPLOAD_TEMP_FILE = "upload/temp/file";
|
||||
protected static final String DELETE_TO_GC = "delete-to-gc/{0}";
|
||||
protected static final String STEP_GET = "step/get/{0}";
|
||||
protected static final String DEBUG = "debug";
|
||||
private static final String UPDATE_STATUS = "update-status";
|
||||
private static final String UPDATE_PRIORITY = "update-priority";
|
||||
|
@ -100,6 +102,8 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
private FileMetadataService fileMetadataService;
|
||||
@Resource
|
||||
private ApiScenarioCsvMapper apiScenarioCsvMapper;
|
||||
@Resource
|
||||
private ApiScenarioService apiScenarioService;
|
||||
private static String fileMetadataId;
|
||||
private static String localFileId;
|
||||
private static ApiScenario addApiScenario;
|
||||
|
@ -565,6 +569,32 @@ public class ApiScenarioControllerTests extends BaseTest {
|
|||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, DEFAULT_GET, addApiScenario.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void getStepDetail() throws Exception {
|
||||
ApiScenarioDetail apiScenarioDetail = apiScenarioService.get(addApiScenario.getId());
|
||||
List<ApiScenarioStepDTO> steps = apiScenarioDetail.getSteps();
|
||||
requestGetStepDetail(steps);
|
||||
|
||||
apiScenarioDetail = apiScenarioService.get(anOtherAddApiScenario.getId());
|
||||
steps = apiScenarioDetail.getSteps();
|
||||
requestGetStepDetail(steps);
|
||||
|
||||
// @@校验权限
|
||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_READ, STEP_GET, addApiScenario.getId());
|
||||
}
|
||||
|
||||
private void requestGetStepDetail(List<? extends ApiScenarioStepCommonDTO> steps) throws Exception {
|
||||
if (CollectionUtils.isEmpty(steps)) {
|
||||
return;
|
||||
}
|
||||
for (ApiScenarioStepCommonDTO step : steps) {
|
||||
this.requestGetWithOk(STEP_GET, step.getId());
|
||||
List<? extends ApiScenarioStepCommonDTO> children = step.getChildren();
|
||||
requestGetStepDetail(children);
|
||||
}
|
||||
}
|
||||
|
||||
private void asserGetApiScenarioSteps(List<? extends ApiScenarioStepCommonDTO> addApiScenarioSteps, List<? extends ApiScenarioStepCommonDTO> steps) {
|
||||
if (addApiScenarioSteps == null || steps == null) {
|
||||
Assertions.assertEquals(addApiScenarioSteps, null);
|
||||
|
|
Loading…
Reference in New Issue