feat(接口测试): 测试计划接口和场景调试

This commit is contained in:
AgAngle 2024-06-07 16:01:38 +08:00 committed by Craftsman
parent dd6b5f8525
commit 4b3a474f1c
23 changed files with 649 additions and 147 deletions

View File

@ -6,6 +6,5 @@ package io.metersphere.sdk.constants;
* @CreateTime: 2023-12-08 10:53
*/
public enum ApiExecuteResourceType {
API_DEBUG, API, API_CASE, API_SCENARIO
// todo plan api
API_DEBUG, API, API_CASE, API_SCENARIO, TEST_PLAN_API_CASE, TEST_PLAN_API_SCENARIO
}

View File

@ -0,0 +1,25 @@
package io.metersphere.api.invoker;
import io.metersphere.api.service.GetRunScriptService;
import io.metersphere.sdk.constants.ApiExecuteResourceType;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: jianxing
* @CreateTime: 2024-02-06 20:48
*/
public class GetRunScriptServiceRegister {
private static final Map<ApiExecuteResourceType, GetRunScriptService> getRunScriptServiceMap = new HashMap<>();
public static void register(ApiExecuteResourceType apiExecuteResourceType, GetRunScriptService getRunScriptService) {
getRunScriptServiceMap.put(apiExecuteResourceType, getRunScriptService);
}
public static GetRunScriptService getRunScriptService(ApiExecuteResourceType apiExecuteResourceType) {
return getRunScriptServiceMap.get(apiExecuteResourceType);
}
}

View File

@ -57,10 +57,10 @@ public class MessageListener {
} else {
ApiExecuteResourceType resourceType = EnumValidator.validateEnum(ApiExecuteResourceType.class, dto.getResourceType());
boolean isStop = switch (resourceType) {
case API_CASE ->
case API_CASE, TEST_PLAN_API_CASE ->
StringUtils.equals(apiReportMapper.selectByPrimaryKey(dto.getReportId()).getExecStatus(), ExecStatus.STOPPED.name())
&& deleteQueue(dto.getQueueId());
case API_SCENARIO ->
case API_SCENARIO, TEST_PLAN_API_SCENARIO ->
StringUtils.equals(apiScenarioReportMapper.selectByPrimaryKey(dto.getReportId()).getExecStatus(), ExecStatus.STOPPED.name())
&& deleteQueue(dto.getQueueId());
default -> false;

View File

@ -1,9 +1,8 @@
package io.metersphere.api.service;
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
import io.metersphere.api.service.definition.ApiReportService;
import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.api.service.scenario.ApiScenarioReportService;
import io.metersphere.api.service.scenario.ApiScenarioRunService;
import io.metersphere.sdk.constants.ApiExecuteResourceType;
import io.metersphere.sdk.constants.ExecStatus;
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
@ -31,10 +30,6 @@ public class ApiExecuteResourceService {
@Resource
private ApiScenarioReportService apiScenarioReportService;
@Resource
private ApiScenarioRunService apiScenarioRunService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private StringRedisTemplate stringRedisTemplate;
@ -45,17 +40,17 @@ public class ApiExecuteResourceService {
LogUtils.info("生成并获取执行脚本: {}", key);
ApiExecuteResourceType apiExecuteResourceType = EnumValidator.validateEnum(ApiExecuteResourceType.class, request.getResourceType());
switch (apiExecuteResourceType) {
case API_SCENARIO -> {
apiScenarioReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
return apiScenarioRunService.getRunScript(request);
}
case API_CASE -> {
apiReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
return apiTestCaseService.getRunScript(request);
}
case API_SCENARIO, TEST_PLAN_API_SCENARIO ->
apiScenarioReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
case API_CASE, TEST_PLAN_API_CASE ->
apiReportService.updateReportStatus(reportId, ExecStatus.RUNNING.name());
default -> throw new MSException("不支持的资源类型: " + request.getResourceType());
}
GetRunScriptService getRunScriptService = GetRunScriptServiceRegister.getRunScriptService(apiExecuteResourceType);
return getRunScriptService.getRunScript(request);
}
public String getRunScript(String reportId, String testId) {

View File

@ -0,0 +1,15 @@
package io.metersphere.api.service;
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
import io.metersphere.sdk.dto.api.task.GetRunScriptResult;
/**
* @Author: jianxing
* @CreateTime: 2024-02-06 20:47
*/
public interface GetRunScriptService {
/**
* 解析并返回执行脚本
*/
GetRunScriptResult getRunScript(GetRunScriptRequest request);
}

View File

@ -7,10 +7,12 @@ import io.metersphere.api.dto.debug.ApiFileResourceUpdateRequest;
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
import io.metersphere.api.dto.definition.*;
import io.metersphere.api.dto.request.ApiTransferRequest;
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
import io.metersphere.api.mapper.*;
import io.metersphere.api.service.ApiCommonService;
import io.metersphere.api.service.ApiExecuteService;
import io.metersphere.api.service.ApiFileResourceService;
import io.metersphere.api.service.GetRunScriptService;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.functional.domain.FunctionalCaseTestExample;
import io.metersphere.functional.mapper.FunctionalCaseTestMapper;
@ -59,7 +61,7 @@ import java.util.stream.Stream;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiTestCaseService extends MoveNodeService {
public class ApiTestCaseService extends MoveNodeService implements GetRunScriptService {
public static final String PRIORITY = "Priority";
public static final String STATUS = "Status";
@ -108,6 +110,10 @@ public class ApiTestCaseService extends MoveNodeService {
@Resource
private FunctionalCaseTestMapper functionalCaseTestMapper;
public ApiTestCaseService() {
GetRunScriptServiceRegister.register(ApiExecuteResourceType.API_CASE, this);
}
private static final String CASE_TABLE = "api_test_case";
private static final int MAX_TAG_SIZE = 10;
@ -204,7 +210,7 @@ public class ApiTestCaseService extends MoveNodeService {
return requestStr;
}
private ApiTestCase checkResourceExist(String id) {
public ApiTestCase checkResourceExist(String id) {
ApiTestCase testCase = apiTestCaseMapper.selectByPrimaryKey(id);
if (testCase == null) {
throw new MSException(Translator.get("api_test_case_not_exist"));
@ -736,7 +742,7 @@ public class ApiTestCaseService extends MoveNodeService {
return doExecute(taskRequest, runRequest, request.getApiDefinitionId(), request.getEnvironmentId());
}
private TaskRequestDTO doExecute(TaskRequestDTO taskRequest, ApiResourceRunRequest runRequest, String apiDefinitionId, String envId) {
public TaskRequestDTO doExecute(TaskRequestDTO taskRequest, ApiResourceRunRequest runRequest, String apiDefinitionId, String envId) {
ApiParamConfig apiParamConfig = apiExecuteService.getApiParamConfig(taskRequest.getTaskItem().getReportId(), taskRequest.getTaskInfo().getProjectId());
@ -753,11 +759,16 @@ public class ApiTestCaseService extends MoveNodeService {
/**
* 获取执行脚本
*/
@Override
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(request.getTaskItem().getResourceId());
return getRunScript(request, apiTestCase);
}
public GetRunScriptResult getRunScript(GetRunScriptRequest request, ApiTestCase apiTestCase) {
TaskItem taskItem = request.getTaskItem();
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(taskItem.getResourceId());
ApiDefinition apiDefinition = apiDefinitionMapper.selectByPrimaryKey(apiTestCase.getApiDefinitionId());
ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(taskItem.getResourceId());
ApiTestCaseBlob apiTestCaseBlob = apiTestCaseBlobMapper.selectByPrimaryKey(apiTestCase.getId());
ApiParamConfig apiParamConfig = apiExecuteService.getApiParamConfig(taskItem.getReportId(), apiTestCase.getProjectId());
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(new String(apiTestCaseBlob.getRequest()), AbstractMsTestElement.class);
@ -804,14 +815,7 @@ public class ApiTestCaseService extends MoveNodeService {
public ApiTestCaseRecord initApiReport(ApiTestCase apiTestCase, String reportId, String poolId, String userId) {
// 初始化报告
ApiReport apiReport = getApiReport(userId);
apiReport.setId(reportId);
apiReport.setTriggerMode(TaskTriggerMode.MANUAL.name());
apiReport.setName(apiTestCase.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
apiReport.setRunMode(ApiBatchRunMode.PARALLEL.name());
apiReport.setPoolId(poolId);
apiReport.setEnvironmentId(apiTestCase.getEnvironmentId());
apiReport.setProjectId(apiTestCase.getProjectId());
ApiReport apiReport = getApiReport(apiTestCase, reportId, poolId, userId);
// 创建报告和用例的关联关系
ApiTestCaseRecord apiTestCaseRecord = getApiTestCaseRecord(apiTestCase, apiReport);
@ -822,7 +826,19 @@ public class ApiTestCaseService extends MoveNodeService {
return apiTestCaseRecord;
}
private ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId, long sort) {
public ApiReport getApiReport(ApiTestCase apiTestCase, String reportId, String poolId, String userId) {
ApiReport apiReport = getApiReport(userId);
apiReport.setId(reportId);
apiReport.setTriggerMode(TaskTriggerMode.MANUAL.name());
apiReport.setName(apiTestCase.getName() + "_" + DateUtils.getTimeString(System.currentTimeMillis()));
apiReport.setRunMode(ApiBatchRunMode.PARALLEL.name());
apiReport.setPoolId(poolId);
apiReport.setEnvironmentId(apiTestCase.getEnvironmentId());
apiReport.setProjectId(apiTestCase.getProjectId());
return apiReport;
}
public ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId, long sort) {
ApiReportStep apiReportStep = new ApiReportStep();
apiReportStep.setReportId(reportId);
apiReportStep.setStepId(apiTestCase.getId());
@ -862,7 +878,7 @@ public class ApiTestCaseService extends MoveNodeService {
public TaskInfo getTaskInfo(String projectId, String runModule) {
TaskInfo taskInfo = apiExecuteService.getTaskInfo(projectId);
taskInfo.setResourceType(ApiResourceType.API_CASE.name());
taskInfo.setResourceType(ApiExecuteResourceType.API_CASE.name());
taskInfo.setRunMode(runModule);
taskInfo.setNeedParseScript(false);
return taskInfo;

View File

@ -10,6 +10,7 @@ import io.metersphere.api.dto.request.MsScenario;
import io.metersphere.api.dto.request.controller.MsScriptElement;
import io.metersphere.api.dto.request.http.MsHTTPElement;
import io.metersphere.api.dto.scenario.*;
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
import io.metersphere.api.mapper.ApiScenarioBlobMapper;
import io.metersphere.api.mapper.ApiScenarioMapper;
import io.metersphere.api.mapper.ApiScenarioReportMapper;
@ -17,6 +18,7 @@ import io.metersphere.api.parser.step.StepParser;
import io.metersphere.api.parser.step.StepParserFactory;
import io.metersphere.api.service.ApiCommonService;
import io.metersphere.api.service.ApiExecuteService;
import io.metersphere.api.service.GetRunScriptService;
import io.metersphere.api.service.definition.ApiDefinitionModuleService;
import io.metersphere.api.service.definition.ApiDefinitionService;
import io.metersphere.api.service.definition.ApiTestCaseService;
@ -30,10 +32,7 @@ import io.metersphere.project.dto.environment.http.HttpConfigModuleMatchRule;
import io.metersphere.project.dto.environment.http.SelectModule;
import io.metersphere.project.service.EnvironmentGroupService;
import io.metersphere.project.service.EnvironmentService;
import io.metersphere.sdk.constants.ApiBatchRunMode;
import io.metersphere.sdk.constants.ApiExecuteRunMode;
import io.metersphere.sdk.constants.ExecStatus;
import io.metersphere.sdk.constants.TaskTriggerMode;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.dto.api.task.*;
import io.metersphere.sdk.util.DateUtils;
import io.metersphere.sdk.util.JSON;
@ -55,7 +54,7 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class ApiScenarioRunService {
public class ApiScenarioRunService implements GetRunScriptService {
@Resource
private ApiScenarioMapper apiScenarioMapper;
@Resource
@ -85,6 +84,10 @@ public class ApiScenarioRunService {
@Resource
private ApiExecutionSetService apiExecutionSetService;
public ApiScenarioRunService() {
GetRunScriptServiceRegister.register(ApiExecuteResourceType.API_SCENARIO, this);
}
public TaskRequestDTO run(String id, String reportId, String userId) {
ApiScenarioDetail apiScenarioDetail = getForRun(id);
@ -260,12 +263,15 @@ public class ApiScenarioRunService {
* 解析并返回执行脚本等信息
*/
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
return getRunScript(request, request.getTaskItem().getResourceId());
}
public GetRunScriptResult getRunScript(GetRunScriptRequest request, String id) {
ApiScenarioDetail apiScenarioDetail = getForRun(id);
TaskItem taskItem = request.getTaskItem();
String id = taskItem.getResourceId();
ApiRunModeConfigDTO runModeConfig = request.getRunModeConfig();
String reportId = taskItem.getReportId();
ApiScenarioDetail apiScenarioDetail = getForRun(id);
if (apiScenarioDetail == null) {
if (runModeConfig.isIntegratedReport()) {
// 用例不存在则在执行集合中删除

View File

@ -1289,7 +1289,7 @@ public class ApiScenarioService extends MoveNodeService {
}
}
private ApiScenario checkResourceExist(String id) {
public ApiScenario checkResourceExist(String id) {
return ServiceUtils.checkResourceExist(apiScenarioMapper.selectByPrimaryKey(id), "permission.system_api_scenario.name");
}

View File

@ -350,7 +350,8 @@ public class ApiDefinitionControllerTests extends BaseTest {
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
}
private ApiDefinitionAddRequest createApiDefinitionAddRequest() {
public static ApiDefinitionAddRequest createApiDefinitionAddRequest() {
ExtBaseProjectVersionMapper extBaseProjectVersionMapper = CommonBeanFactory.getBean(ExtBaseProjectVersionMapper.class);
// 创建并返回一个 ApiDefinitionAddRequest 对象用于测试
String defaultVersion = extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID);
ApiDefinitionAddRequest request = new ApiDefinitionAddRequest();
@ -369,7 +370,7 @@ public class ApiDefinitionControllerTests extends BaseTest {
return request;
}
private List<ApiDefinitionCustomField> createCustomFields() {
private static List<ApiDefinitionCustomField> createCustomFields() {
List<ApiDefinitionCustomField> list = new ArrayList<>();
ApiDefinitionCustomField customField = new ApiDefinitionCustomField();
customField.setFieldId("custom-field");

View File

@ -47,6 +47,7 @@ import io.metersphere.sdk.file.FileRequest;
import io.metersphere.sdk.mapper.EnvironmentGroupMapper;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
@ -343,16 +344,7 @@ public class ApiScenarioControllerTests extends BaseTest {
initTestData();
// @@请求成功
ApiScenarioAddRequest request = new ApiScenarioAddRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setDescription("desc");
request.setName("test name");
request.setModuleId("default");
request.setGrouped(false);
request.setEnvironmentId(envId);
request.setTags(List.of("tag1", "tag2"));
request.setPriority("P0");
request.setStatus(ApiScenarioStatus.COMPLETED.name());
ApiScenarioAddRequest request = getApiScenarioAddRequest();
List<ApiScenarioStepRequest> steps = getApiScenarioStepRequests();
Map<String, Object> steptDetailMap = new HashMap<>();
steptDetailMap.put(steps.get(1).getId(), getMsHttpElementParam());
@ -403,6 +395,20 @@ public class ApiScenarioControllerTests extends BaseTest {
requestPostPermissionTest(PermissionConstants.PROJECT_API_SCENARIO_ADD, DEFAULT_ADD, request);
}
public static ApiScenarioAddRequest getApiScenarioAddRequest() {
ApiScenarioAddRequest request = new ApiScenarioAddRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setDescription("desc");
request.setName("test name");
request.setModuleId("default");
request.setGrouped(false);
request.setEnvironmentId(envId);
request.setTags(List.of("tag1", "tag2"));
request.setPriority("P0");
request.setStatus(ApiScenarioStatus.COMPLETED.name());
return request;
}
private Object getMsHttpElementParam() {
return getMsHttpElementStr(MsHTTPElementTest.getMsHttpElement());
}
@ -446,7 +452,15 @@ public class ApiScenarioControllerTests extends BaseTest {
}
}
private ScenarioConfig getScenarioConfig() {
public ScenarioConfig getScenarioConfig() {
ScenarioConfig scenarioConfig = getSimpleScenarioConfig();
ScenarioVariable scenarioVariable = new ScenarioVariable();
scenarioVariable.setCsvVariables(getCsvVariables());
scenarioConfig.setVariable(scenarioVariable);
return scenarioConfig;
}
public ScenarioConfig getSimpleScenarioConfig() {
ScenarioConfig scenarioConfig = new ScenarioConfig();
MsAssertionConfig msAssertionConfig = new MsAssertionConfig();
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
@ -462,9 +476,6 @@ public class ApiScenarioControllerTests extends BaseTest {
scenarioOtherConfig.setFailureStrategy(ScenarioOtherConfig.FailureStrategy.CONTINUE.name());
scenarioOtherConfig.setEnableCookieShare(true);
scenarioConfig.setOtherConfig(scenarioOtherConfig);
ScenarioVariable scenarioVariable = new ScenarioVariable();
scenarioVariable.setCsvVariables(getCsvVariables());
scenarioConfig.setVariable(scenarioVariable);
return scenarioConfig;
}
@ -480,7 +491,7 @@ public class ApiScenarioControllerTests extends BaseTest {
fileMetadataId = fileMetadataService.upload(fileUploadRequest, "admin", file);
}
public List<CsvVariable> getCsvVariables() {
public static List<CsvVariable> getCsvVariables() {
List<CsvVariable> csvVariables = new ArrayList<>();
CsvVariable csvVariable = new CsvVariable();
csvVariable.setId(UUID.randomUUID().toString());
@ -498,6 +509,7 @@ public class ApiScenarioControllerTests extends BaseTest {
csvVariable.setName("csv-关联的");
file = new ApiFile();
file.setFileId(fileMetadataId);
FileMetadataService fileMetadataService = CommonBeanFactory.getBean(FileMetadataService.class);
FileMetadata fileMetadata = fileMetadataService.selectById(fileMetadataId);
file.setFileName(fileMetadata.getOriginalName());
file.setLocal(false);

View File

@ -1,14 +0,0 @@
-- 初始化用于权限测试的组织用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('PROJECT', 'PROJECT', 'PROJECT@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 PROJECT 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('PROJECT', '项目级别权限校验', '', 1, 'PROJECT', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'PROJECT', 'PROJECT', 'PROJECT', id, organization_id, 1684747668375, 'admin' FROM project WHERE num = 100001;

View File

@ -1,14 +0,0 @@
-- 初始化用于权限测试的组织用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('PROJECT', 'PROJECT', 'PROJECT@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 PROJECT 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('PROJECT', '项目级别权限校验', '', 1, 'PROJECT', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'PROJECT', 'PROJECT', 'PROJECT', id, organization_id, 1684747668375, 'admin' FROM project WHERE num = 100001;

View File

@ -63,6 +63,9 @@ spring.messages.basename=i18n/commons,i18n/api,i18n/bug,i18n/case,i18n/plan,i18n
# actuator
management.endpoints.web.exposure.include=*
management.endpoints.enabled-by-default=false
# 单元测试初始化权限 sql
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath*:dml/init_permission_test.sql
# redis
spring.session.timeout=43200s
spring.data.redis.host=${embedded.redis.host}

View File

@ -47,7 +47,7 @@ VALUES ('CASE_REVIEW_REAL_MODULE_ID', 'project-gyq-case-review-test', '用例评
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('gyq_review_test', 'gyq_review_test', 'PROJECT@fit2cloud.com', MD5('metersphere'),UNIX_TIMESTAMP() * 1000,UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false),
VALUES ('gyq_review_test', 'gyq_review_test', 'gyq_review_test@fit2cloud.com', MD5('metersphere'),UNIX_TIMESTAMP() * 1000,UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false),
('gyq_review_test2', 'default-Administrator-1', 'admin-default-user@metersphere.io', MD5('metersphere'), UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);

View File

@ -1,14 +0,0 @@
-- 初始化用于权限测试的组织用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('PROJECT', 'PROJECT', 'PROJECT@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 PROJECT 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('PROJECT', '项目级别权限校验', '', 1, 'PROJECT', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'PROJECT', 'PROJECT', 'PROJECT', id, organization_id, 1684747668375, 'admin' FROM project WHERE num = 100001;

View File

@ -27,3 +27,20 @@ VALUES ('ORGANIZATION', '组织级别权限校验', '', 1, 'ORGANIZATION', 16206
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'ORGANIZATION', 'ORGANIZATION', 'ORGANIZATION', id, id, 1684747668375, 'admin' FROM organization WHERE num = 100001;
-- 初始化用于项目级别权限测试的用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('PROJECT', 'PROJECT', 'PROJECT@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 PROJECT 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('PROJECT', '项目级别权限校验', '', 1, 'PROJECT', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'PROJECT', 'PROJECT', 'PROJECT', id, organization_id, 1684747668375, 'admin' FROM project WHERE num = 100001;

View File

@ -10,6 +10,7 @@ import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.plan.service.TestPlanService;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
import io.metersphere.system.dto.LogInsertModule;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import io.metersphere.system.log.annotation.Log;
@ -19,15 +20,13 @@ import io.metersphere.system.utils.PageUtils;
import io.metersphere.system.utils.Pager;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@ -104,6 +103,16 @@ public class TestPlanApiCaseController {
testPlanApiCaseService.batchUpdateExecutor(request);
}
@GetMapping("/run/{id}")
@Operation(summary = "用例执行")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
// @CheckOwner(resourceId = "#id", resourceType = "test_plan_api_case") todo
public TaskRequestDTO run(@PathVariable String id,
@Schema(description = "报告ID传了可以实时获取结果不传则不支持实时获取")
@RequestParam(required = false) String reportId) {
return testPlanApiCaseService.run(id, reportId, SessionUtils.getUserId());
}
//TODO 批量移动 计划集内
}

View File

@ -1,13 +1,28 @@
package io.metersphere.plan.controller;
import io.metersphere.plan.service.TestPlanApiScenarioService;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
import io.metersphere.system.utils.SessionUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
@Tag(name = "测试计划场景用例")
@RestController
@RequestMapping("/test-plan/api/scenario")
public class TestPlanApiScenarioController {
@Resource
private TestPlanApiScenarioService testPlanApiScenarioService;
@GetMapping("/run/{id}")
@Operation(summary = "接口测试-接口场景管理-场景执行")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_EXECUTE)
// @CheckOwner(resourceId = "#id", resourceType = "test_plan_api_scenario")
public TaskRequestDTO run(@PathVariable String id, @RequestParam(required = false) String reportId) {
return testPlanApiScenarioService.run(id, reportId, SessionUtils.getUserId());
}
}

View File

@ -1,12 +1,15 @@
package io.metersphere.plan.service;
import io.metersphere.api.domain.ApiTestCase;
import io.metersphere.api.domain.ApiTestCaseExample;
import io.metersphere.api.domain.*;
import io.metersphere.api.dto.definition.ApiDefinitionDTO;
import io.metersphere.api.dto.definition.ApiTestCaseDTO;
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
import io.metersphere.api.mapper.ApiTestCaseMapper;
import io.metersphere.api.service.ApiExecuteService;
import io.metersphere.api.service.GetRunScriptService;
import io.metersphere.api.service.definition.ApiDefinitionModuleService;
import io.metersphere.api.service.definition.ApiDefinitionService;
import io.metersphere.api.service.definition.ApiReportService;
import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
import io.metersphere.functional.dto.ProjectOptionDTO;
@ -27,12 +30,11 @@ import io.metersphere.project.domain.ProjectExample;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.dto.MoveNodeSortDTO;
import io.metersphere.project.mapper.ProjectMapper;
import io.metersphere.sdk.constants.CaseType;
import io.metersphere.sdk.constants.ModuleConstants;
import io.metersphere.sdk.constants.TestPlanResourceConstants;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.domain.Environment;
import io.metersphere.sdk.domain.EnvironmentExample;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.dto.api.task.*;
import io.metersphere.sdk.mapper.EnvironmentMapper;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.Translator;
@ -40,6 +42,7 @@ import io.metersphere.system.dto.LogInsertModule;
import io.metersphere.system.dto.sdk.BaseTreeNode;
import io.metersphere.system.service.UserLoginService;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
@ -60,7 +63,7 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanApiCaseService extends TestPlanResourceService {
public class TestPlanApiCaseService extends TestPlanResourceService implements GetRunScriptService {
@Resource
private TestPlanMapper testPlanMapper;
@ -73,6 +76,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ApiReportService apiReportService;
@Resource
private ProjectMapper projectMapper;
@Resource
private EnvironmentMapper environmentMapper;
@ -84,11 +89,17 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
private ApiExecuteService apiExecuteService;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
@Resource
private TestPlanResourceLogService testPlanResourceLogService;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
public TestPlanApiCaseService() {
GetRunScriptServiceRegister.register(ApiExecuteResourceType.TEST_PLAN_API_CASE, this);
}
@Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
@ -505,7 +516,6 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
}
}
/**
* 构建测试计划接口用例对象
*
@ -561,4 +571,84 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
testPlanResourceLogService.saveSortLog(testPlan, request.getMoveId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_API_CASE, logInsertModule));
return response;
}
public TaskRequestDTO run(String id, String reportId, String userId) {
TestPlanApiCase testPlanApiCase = checkResourceExist(id);
ApiTestCase apiTestCase = apiTestCaseService.checkResourceExist(testPlanApiCase.getApiCaseId());
String poolId = "todo";
ApiRunModeConfigDTO runModeConfig = new ApiRunModeConfigDTO();
// todo 设置 runModeConfig 配置
TaskRequestDTO taskRequest = getTaskRequest(reportId, id, apiTestCase.getProjectId(), ApiExecuteRunMode.RUN.name());
TaskInfo taskInfo = taskRequest.getTaskInfo();
TaskItem taskItem = taskRequest.getTaskItem();
taskInfo.setRunModeConfig(runModeConfig);
taskInfo.setSaveResult(true);
taskInfo.setRealTime(true);
if (StringUtils.isEmpty(taskItem.getReportId())) {
taskInfo.setRealTime(false);
reportId = IDGenerator.nextStr();
taskItem.setReportId(reportId);
} else {
// 如果传了报告ID则实时获取结果
taskInfo.setRealTime(true);
}
// 初始化报告
initApiReport(apiTestCase, testPlanApiCase, reportId, poolId, userId);
return apiExecuteService.execute(taskRequest);
}
public TestPlanApiCase checkResourceExist(String id) {
return ServiceUtils.checkResourceExist(testPlanApiCaseMapper.selectByPrimaryKey(id), "api_test_case_not_exist");
}
/**
* 获取执行脚本
*/
@Override
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
TaskItem taskItem = request.getTaskItem();
TestPlanApiCase testPlanApiCase = testPlanApiCaseMapper.selectByPrimaryKey(taskItem.getResourceId());
ApiTestCase apiTestCase = apiTestCaseMapper.selectByPrimaryKey(testPlanApiCase.getApiCaseId());
return apiTestCaseService.getRunScript(request, apiTestCase);
}
/**
* 预生成用例的执行报告
*
* @param apiTestCase
* @param poolId
* @param userId
* @return
*/
public ApiTestCaseRecord initApiReport(ApiTestCase apiTestCase, TestPlanApiCase testPlanApiCase, String reportId, String poolId, String userId) {
// 初始化报告
ApiReport apiReport = apiTestCaseService.getApiReport(apiTestCase, reportId, poolId, userId);
apiReport.setTestPlanCaseId(testPlanApiCase.getTestPlanId());
// 创建报告和用例的关联关系
ApiTestCaseRecord apiTestCaseRecord = apiTestCaseService.getApiTestCaseRecord(apiTestCase, apiReport);
apiReportService.insertApiReport(List.of(apiReport), List.of(apiTestCaseRecord));
//初始化步骤
apiReportService.insertApiReportStep(List.of(getApiReportStep(apiTestCase, reportId)));
return apiTestCaseRecord;
}
public ApiReportStep getApiReportStep(ApiTestCase apiTestCase, String reportId) {
ApiReportStep apiReportStep = apiTestCaseService.getApiReportStep(apiTestCase, reportId, 1L);
apiReportStep.setStepType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
return apiReportStep;
}
public TaskRequestDTO getTaskRequest(String reportId, String resourceId, String projectId, String runModule) {
TaskRequestDTO taskRequest = apiTestCaseService.getTaskRequest(reportId, resourceId, projectId, runModule);
taskRequest.getTaskInfo().setResourceType(ApiExecuteResourceType.TEST_PLAN_API_CASE.name());
taskRequest.getTaskInfo().setNeedParseScript(true);
return taskRequest;
}
}

View File

@ -1,6 +1,12 @@
package io.metersphere.plan.service;
import io.metersphere.api.domain.ApiScenario;
import io.metersphere.api.domain.ApiScenarioReport;
import io.metersphere.api.dto.scenario.ApiScenarioDTO;
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
import io.metersphere.api.service.ApiExecuteService;
import io.metersphere.api.service.GetRunScriptService;
import io.metersphere.api.service.scenario.ApiScenarioRunService;
import io.metersphere.api.service.scenario.ApiScenarioService;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.domain.TestPlan;
@ -15,13 +21,14 @@ import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
import io.metersphere.plan.mapper.*;
import io.metersphere.project.dto.MoveNodeSortDTO;
import io.metersphere.sdk.constants.CaseType;
import io.metersphere.sdk.constants.TestPlanResourceConstants;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.dto.api.task.*;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.Translator;
import io.metersphere.system.dto.LogInsertModule;
import io.metersphere.system.uid.IDGenerator;
import io.metersphere.system.utils.ServiceUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ExecutorType;
@ -38,7 +45,7 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class TestPlanApiScenarioService extends TestPlanResourceService {
public class TestPlanApiScenarioService extends TestPlanResourceService implements GetRunScriptService {
@Resource
private SqlSessionFactory sqlSessionFactory;
@Resource
@ -46,13 +53,19 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
@Resource
private ExtTestPlanApiScenarioMapper extTestPlanApiScenarioMapper;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
@Resource
private ApiScenarioService apiScenarioService;
@Resource
private TestPlanMapper testPlanMapper;
@Resource
private TestPlanResourceLogService testPlanResourceLogService;
@Resource
private ApiScenarioRunService apiScenarioRunService;
@Resource
private ApiExecuteService apiExecuteService;
public TestPlanApiScenarioService() {
GetRunScriptServiceRegister.register(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO, this);
}
@Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
@ -137,7 +150,6 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
scenarioBatchMapper.updateByExampleSelective(record, scenarioCaseExample);
}
/**
* 未关联接口场景列表
*
@ -167,4 +179,59 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
testPlanResourceLogService.saveSortLog(testPlan, request.getMoveId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_API_CASE, logInsertModule));
return response;
}
public TaskRequestDTO run(String id, String reportId, String userId) {
TestPlanApiScenario testPlanApiScenario = checkResourceExist(id);
ApiScenario apiScenario = apiScenarioService.checkResourceExist(testPlanApiScenario.getApiScenarioId());
String poolId = "todo";
String envId = "todo";
ApiRunModeConfigDTO runModeConfig = new ApiRunModeConfigDTO();
// todo 设置 runModeConfig 配置
TaskRequestDTO taskRequest = getTaskRequest(reportId, id, apiScenario.getProjectId(), ApiExecuteRunMode.RUN.name());
TaskInfo taskInfo = taskRequest.getTaskInfo();
TaskItem taskItem = taskRequest.getTaskItem();
taskInfo.setRunModeConfig(runModeConfig);
taskInfo.setSaveResult(true);
taskInfo.setRealTime(true);
if (StringUtils.isEmpty(taskItem.getReportId())) {
taskInfo.setRealTime(false);
reportId = IDGenerator.nextStr();
taskItem.setReportId(reportId);
} else {
// 如果传了报告ID则实时获取结果
taskInfo.setRealTime(true);
}
ApiScenarioReport scenarioReport = apiScenarioRunService.getScenarioReport(userId);
scenarioReport.setId(reportId);
scenarioReport.setTriggerMode(TaskTriggerMode.MANUAL.name());
scenarioReport.setRunMode(ApiBatchRunMode.PARALLEL.name());
scenarioReport.setPoolId(poolId);
scenarioReport.setEnvironmentId(envId);
scenarioReport.setTestPlanScenarioId(testPlanApiScenario.getId());
apiScenarioRunService.initApiReport(apiScenario, scenarioReport);
return apiExecuteService.execute(taskRequest);
}
public TestPlanApiScenario checkResourceExist(String id) {
return ServiceUtils.checkResourceExist(testPlanApiScenarioMapper.selectByPrimaryKey(id), "permission.system_api_scenario.name");
}
public TaskRequestDTO getTaskRequest(String reportId, String resourceId, String projectId, String runModule) {
TaskRequestDTO taskRequest = apiScenarioRunService.getTaskRequest(reportId, resourceId, projectId, runModule);
taskRequest.getTaskInfo().setResourceType(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO.name());
taskRequest.getTaskInfo().setNeedParseScript(true);
return taskRequest;
}
@Override
public GetRunScriptResult getRunScript(GetRunScriptRequest request) {
TaskItem taskItem = request.getTaskItem();
TestPlanApiScenario testPlanApiScenario = testPlanApiScenarioMapper.selectByPrimaryKey(taskItem.getResourceId());
return apiScenarioRunService.getRunScript(request, testPlanApiScenario.getApiScenarioId());
}
}

View File

@ -1,8 +1,28 @@
package io.metersphere.plan.controller;
import io.metersphere.api.constants.ApiConstants;
import io.metersphere.api.constants.ApiDefinitionStatus;
import io.metersphere.api.controller.result.ApiResultCode;
import io.metersphere.api.domain.ApiDefinition;
import io.metersphere.api.domain.ApiTestCase;
import io.metersphere.api.dto.definition.ApiDefinitionAddRequest;
import io.metersphere.api.dto.definition.ApiTestCaseAddRequest;
import io.metersphere.api.dto.request.http.MsHTTPElement;
import io.metersphere.api.dto.request.http.body.Body;
import io.metersphere.api.dto.request.http.body.RawBody;
import io.metersphere.api.service.definition.ApiDefinitionService;
import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.domain.TestPlanApiCase;
import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
import io.metersphere.sdk.constants.PermissionConstants;
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
import io.metersphere.sdk.dto.api.task.TaskItem;
import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder;
@ -15,25 +35,41 @@ import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestPlanApiCaseControllerTests extends BaseTest {
public static final String API_CASE_PAGE = "/test-plan/api/case/page";
public static final String API_CASE_TREE_COUNT = "/test-plan/api/case/module/count";
public static final String API_CASE_TREE_MODULE_TREE = "/test-plan/api/case/tree";
public static final String API_CASE_DISASSOCIATE = "/test-plan/api/case/disassociate";
public static final String API_CASE_BATCH_DISASSOCIATE = "/test-plan/api/case/batch/disassociate";
public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "/test-plan/api/case/batch/update/executor";
private static final String BASE_PATH = "/test-plan/api/case/";
public static final String API_CASE_PAGE = "page";
public static final String API_CASE_TREE_COUNT = "module/count";
public static final String API_CASE_TREE_MODULE_TREE = "tree";
public static final String API_CASE_DISASSOCIATE = "disassociate";
public static final String API_CASE_BATCH_DISASSOCIATE = "batch/disassociate";
public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "batch/update/executor";
public static final String RUN = "run/{0}";
public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}";
@Resource
private TestPlanApiCaseService testPlanApiCaseService;
@Resource
private ApiTestCaseService apiTestCaseService;
@Resource
private ApiDefinitionService apiDefinitionService;
@Resource
private TestPlanApiCaseMapper testPlanApiCaseMapper;
private static ApiTestCase apiTestCase;
private static TestPlanApiCase testPlanApiCase;
@Override
public String getBasePath() {
return BASE_PATH;
}
@Test
@Order(1)
@ -56,7 +92,6 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
Assertions.assertNotNull(resultHolder);
}
@Test
@Order(2)
public void testApiCaseCount() throws Exception {
@ -146,7 +181,7 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
@Test
@Order(6)
public void testApiCaseAssociate() throws Exception {
public void testApiCaseAssociate() {
// api
Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates = new HashMap<>();
List<BaseCollectionAssociateRequest> baseCollectionAssociateRequests = new ArrayList<>();
@ -167,5 +202,83 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
collectionAssociates1.put(AssociateCaseType.API_CASE, baseCollectionAssociateRequests1);
testPlanApiCaseService.associateCollection("wxxx_2", collectionAssociates1, "wx");
apiTestCase = initApiData();
TestPlanApiCase testPlanApiCase = new TestPlanApiCase();
testPlanApiCase.setApiCaseId(apiTestCase.getId());
testPlanApiCase.setTestPlanId("wxxx_1");
testPlanApiCase.setTestPlanCollectionId("wxxx_1");
testPlanApiCase.setId(UUID.randomUUID().toString());
testPlanApiCase.setCreateTime(System.currentTimeMillis());
testPlanApiCase.setCreateUser("admin");
testPlanApiCase.setPos(0L);
testPlanApiCaseMapper.insert(testPlanApiCase);
this.testPlanApiCase = testPlanApiCase;
// todo 关联的接口测试
}
@Test
@Order(7)
public void run() throws Exception {
assertErrorCode(this.requestGet(RUN, testPlanApiCase.getId()), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
assertErrorCode(this.requestGet(RUN_WITH_REPORT_ID, testPlanApiCase.getId(), "reportId"), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
assertErrorCode(this.requestGet(RUN, "11"), NOT_FOUND);
GetRunScriptRequest request = new GetRunScriptRequest();
TaskItem taskItem = new TaskItem();
taskItem.setResourceId(testPlanApiCase.getId());
taskItem.setReportId("reportId");
request.setTaskItem(taskItem);
testPlanApiCaseService.getRunScript(request);
requestGetPermissionTest(PermissionConstants.TEST_PLAN_READ_EXECUTE, RUN, testPlanApiCase.getId());
}
public ApiTestCase initApiData() {
ApiDefinitionAddRequest apiDefinitionAddRequest = createApiDefinitionAddRequest();
MsHTTPElement msHttpElement = new MsHTTPElement();
msHttpElement.setPath("/test");
msHttpElement.setMethod("GET");
msHttpElement.setName("name");
msHttpElement.setEnable(true);
Body body = new Body();
body.setBodyType(Body.BodyType.RAW.name());
body.setRawBody(new RawBody());
msHttpElement.setBody(body);
apiDefinitionAddRequest.setRequest(getTestElementParam(msHttpElement));
ApiDefinition apiDefinition = apiDefinitionService.create(apiDefinitionAddRequest, "admin");
apiDefinitionAddRequest.setName(UUID.randomUUID().toString());
ApiTestCaseAddRequest caseAddRequest = new ApiTestCaseAddRequest();
caseAddRequest.setApiDefinitionId(apiDefinition.getId());
caseAddRequest.setName(UUID.randomUUID().toString());
caseAddRequest.setProjectId(DEFAULT_PROJECT_ID);
caseAddRequest.setPriority("P0");
caseAddRequest.setStatus(ApiDefinitionStatus.PROCESSING.name());
caseAddRequest.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
caseAddRequest.setEnvironmentId("envId");
caseAddRequest.setRequest(getTestElementParam(msHttpElement));
return apiTestCaseService.addCase(caseAddRequest, "admin");
}
public static ApiDefinitionAddRequest createApiDefinitionAddRequest() {
ExtBaseProjectVersionMapper extBaseProjectVersionMapper = CommonBeanFactory.getBean(ExtBaseProjectVersionMapper.class);
String defaultVersion = extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID);
ApiDefinitionAddRequest request = new ApiDefinitionAddRequest();
request.setName(UUID.randomUUID().toString());
request.setProtocol(ApiConstants.HTTP_PROTOCOL);
request.setProjectId(DEFAULT_PROJECT_ID);
request.setMethod("POST");
request.setPath("/api/admin/posts");
request.setStatus(ApiDefinitionStatus.PROCESSING.name());
request.setModuleId("default");
request.setVersionId(defaultVersion);
request.setDescription("描述内容");
request.setTags(new LinkedHashSet<>(List.of("tag1", "tag2")));
request.setCustomFields(List.of());
return request;
}
private Object getTestElementParam(MsHTTPElement msHttpElement) {
return JSON.parseObject(ApiDataUtils.toJSONString(msHttpElement));
}
}

View File

@ -0,0 +1,175 @@
package io.metersphere.plan.controller;
import io.metersphere.api.constants.ApiScenarioStatus;
import io.metersphere.api.constants.ApiScenarioStepRefType;
import io.metersphere.api.constants.ApiScenarioStepType;
import io.metersphere.api.controller.result.ApiResultCode;
import io.metersphere.api.domain.ApiScenario;
import io.metersphere.api.dto.assertion.MsAssertionConfig;
import io.metersphere.api.dto.request.http.MsHTTPElement;
import io.metersphere.api.dto.request.http.body.Body;
import io.metersphere.api.dto.request.http.body.RawBody;
import io.metersphere.api.dto.scenario.ApiScenarioAddRequest;
import io.metersphere.api.dto.scenario.ApiScenarioStepRequest;
import io.metersphere.api.dto.scenario.ScenarioConfig;
import io.metersphere.api.dto.scenario.ScenarioOtherConfig;
import io.metersphere.api.service.scenario.ApiScenarioService;
import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.plan.domain.TestPlanApiScenario;
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
import io.metersphere.plan.service.TestPlanApiScenarioService;
import io.metersphere.project.api.assertion.MsResponseCodeAssertion;
import io.metersphere.project.api.assertion.MsScriptAssertion;
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
import io.metersphere.sdk.constants.MsAssertionCondition;
import io.metersphere.sdk.dto.api.task.GetRunScriptRequest;
import io.metersphere.sdk.dto.api.task.TaskItem;
import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest;
import io.metersphere.system.uid.IDGenerator;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static io.metersphere.system.controller.handler.result.MsHttpResultCode.NOT_FOUND;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TestPlanApiScenarioControllerTests extends BaseTest {
private static final String BASE_PATH = "/test-plan/api/scenario/";
public static final String RUN = "run/{0}";
public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}";
@Resource
private TestPlanApiScenarioService testPlanApiScenarioService;
@Resource
private ApiScenarioService apiScenarioService;
@Resource
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
private static ApiScenario apiScenario;
private static TestPlanApiScenario testPlanApiScenario;
@Resource
private ExtBaseProjectVersionMapper extBaseProjectVersionMapper;
@Override
public String getBasePath() {
return BASE_PATH;
}
@Test
@Order(1)
public void associate() {
apiScenario = initApiData();
TestPlanApiScenario testPlanApiScenario = new TestPlanApiScenario();
testPlanApiScenario.setApiScenarioId(apiScenario.getId());
testPlanApiScenario.setTestPlanId("wxxx_1");
testPlanApiScenario.setTestPlanCollectionId("wxxx_1");
testPlanApiScenario.setId(UUID.randomUUID().toString());
testPlanApiScenario.setCreateTime(System.currentTimeMillis());
testPlanApiScenario.setCreateUser("admin");
testPlanApiScenario.setPos(0L);
testPlanApiScenarioMapper.insert(testPlanApiScenario);
this.testPlanApiScenario = testPlanApiScenario;
// todo 关联的接口测试
}
@Test
@Order(2)
public void run() throws Exception {
assertErrorCode(this.requestGet(RUN, testPlanApiScenario.getId()), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
assertErrorCode(this.requestGet(RUN_WITH_REPORT_ID, testPlanApiScenario.getId(), "reportId"), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
assertErrorCode(this.requestGet(RUN, "11"), NOT_FOUND);
GetRunScriptRequest request = new GetRunScriptRequest();
TaskItem taskItem = new TaskItem();
taskItem.setResourceId(testPlanApiScenario.getId());
taskItem.setReportId("reportId");
request.setTaskItem(taskItem);
testPlanApiScenarioService.getRunScript(request);
}
public ApiScenario initApiData() {
ApiScenarioAddRequest request = getApiScenarioAddRequest();
ApiScenarioStepRequest stepRequest = new ApiScenarioStepRequest();
stepRequest.setId(IDGenerator.nextStr());
stepRequest.setVersionId(extBaseProjectVersionMapper.getDefaultVersion(DEFAULT_PROJECT_ID));
stepRequest.setConfig(new HashMap<>());
stepRequest.setEnable(true);
stepRequest.setName(UUID.randomUUID().toString());
stepRequest.setRefType(ApiScenarioStepRefType.DIRECT.name());
stepRequest.setStepType(ApiScenarioStepType.CUSTOM_REQUEST.name());
stepRequest.setProjectId(DEFAULT_PROJECT_ID);
stepRequest.setConfig(new HashMap<>());
List<ApiScenarioStepRequest> steps = List.of(stepRequest);
Map<String, Object> steptDetailMap = new HashMap<>();
steptDetailMap.put(stepRequest.getId(), getMsHttpElementParam());
request.setSteps(steps);
request.setStepDetails(steptDetailMap);
request.setScenarioConfig(getScenarioConfig());
return apiScenarioService.add(request, "admin");
}
public ScenarioConfig getScenarioConfig() {
ScenarioConfig scenarioConfig = new ScenarioConfig();
MsAssertionConfig msAssertionConfig = new MsAssertionConfig();
MsScriptAssertion scriptAssertion = new MsScriptAssertion();
scriptAssertion.setScript("{}");
scriptAssertion.setName("script");
msAssertionConfig.setAssertions(List.of(scriptAssertion));
MsResponseCodeAssertion responseCodeAssertion = new MsResponseCodeAssertion();
responseCodeAssertion.setExpectedValue("200");
responseCodeAssertion.setCondition(MsAssertionCondition.EMPTY.name());
responseCodeAssertion.setName("test");
scenarioConfig.getAssertionConfig().getAssertions().add(responseCodeAssertion);
ScenarioOtherConfig scenarioOtherConfig = new ScenarioOtherConfig();
scenarioOtherConfig.setFailureStrategy(ScenarioOtherConfig.FailureStrategy.CONTINUE.name());
scenarioOtherConfig.setEnableCookieShare(true);
scenarioConfig.setOtherConfig(scenarioOtherConfig);
return scenarioConfig;
}
public static ApiScenarioAddRequest getApiScenarioAddRequest() {
ApiScenarioAddRequest request = new ApiScenarioAddRequest();
request.setProjectId(DEFAULT_PROJECT_ID);
request.setDescription("desc");
request.setName("test name");
request.setModuleId("default");
request.setGrouped(false);
request.setEnvironmentId("envID");
request.setTags(List.of("tag1", "tag2"));
request.setPriority("P0");
request.setStatus(ApiScenarioStatus.COMPLETED.name());
return request;
}
private Object getMsHttpElementParam() {
MsHTTPElement msHTTPElement = new MsHTTPElement();
msHTTPElement.setPath("/test");
msHTTPElement.setMethod("GET");
msHTTPElement.setName("name");
msHTTPElement.setEnable(true);
Body body = new Body();
body.setBodyType(Body.BodyType.RAW.name());
body.setRawBody(new RawBody());
msHTTPElement.setBody(body);
return getMsHttpElementStr(msHTTPElement);
}
private Object getMsHttpElementStr(MsHTTPElement msHTTPElement) {
return JSON.parseObject(ApiDataUtils.toJSONString(msHTTPElement));
}
}

View File

@ -1,14 +0,0 @@
-- 初始化用于权限测试的组织用户
INSERT INTO user(id, name, email, password, create_time, update_time, language, last_organization_id, phone, source,
last_project_id, create_user, update_user, deleted)
VALUES ('PROJECT', 'PROJECT', 'PROJECT@fit2cloud.com', MD5('metersphere'),
UNIX_TIMESTAMP() * 1000,
UNIX_TIMESTAMP() * 1000, NULL, NUll, '', 'LOCAL', NULL, 'admin', 'admin', false);
-- 初始化一个用于权限测试的用户组,这里默认使用 PROJECT 作为ID如果是组织和项目级别类似便于根据权限的前缀找到对应测试的用户组
INSERT INTO user_role (id, name, description, internal, type, create_time, update_time, create_user, scope_id)
VALUES ('PROJECT', '项目级别权限校验', '', 1, 'PROJECT', 1620674220005, 1620674220000, 'admin', 'global');
-- 初始化用户和组的关系
INSERT INTO user_role_relation (id, user_id, role_id, source_id, organization_id, create_time, create_user)
SELECT 'PROJECT', 'PROJECT', 'PROJECT', id, organization_id, 1684747668375, 'admin' FROM project WHERE num = 100001;