feat(测试计划): 测试计划批量执行方法开发

This commit is contained in:
Jianguo-Genius 2024-06-11 11:56:19 +08:00 committed by 刘瑞斌
parent b828dfec49
commit bcb92cb79e
5 changed files with 303 additions and 101 deletions

View File

@ -8,16 +8,28 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class TestPlanExecutionQueue { public class TestPlanExecutionQueue {
private String queueId;
private String parentQueueId;
private String testPlanId;
//顺序 //顺序
private long pos; private long pos;
//创建人
private String createUser;
//创建时间
private long createTime;
//队列ID
private String queueId;
// 队列类型
private String queueType;
//父类队列ID
private String parentQueueId;
//父类队列ID
private String parentQueueType;
//资源ID测试集/测试计划/测试计划组)
private String sourceID;
//执行模式 //执行模式
private String runMode; private String runMode;
//执行来源 //执行来源
private String executionSource; private String executionSource;
//预生成报告ID
private String prepareReportId; private String prepareReportId;
private String createUser;
private long createTime; private boolean isLastNode;
} }

View File

@ -2,11 +2,14 @@ package io.metersphere.plan.controller;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import io.metersphere.plan.constants.TestPlanResourceConfig;
import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse; import io.metersphere.plan.dto.response.TestPlanApiCasePageResponse;
import io.metersphere.plan.dto.response.TestPlanAssociationResponse; import io.metersphere.plan.dto.response.TestPlanAssociationResponse;
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
import io.metersphere.plan.service.TestPlanApiCaseLogService; import io.metersphere.plan.service.TestPlanApiCaseLogService;
import io.metersphere.plan.service.TestPlanApiCaseService; import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.plan.service.TestPlanManagementService;
import io.metersphere.plan.service.TestPlanService; import io.metersphere.plan.service.TestPlanService;
import io.metersphere.sdk.constants.HttpMethodConstants; import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.PermissionConstants; import io.metersphere.sdk.constants.PermissionConstants;
@ -28,6 +31,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -39,8 +43,18 @@ public class TestPlanApiCaseController {
@Resource @Resource
private TestPlanApiCaseService testPlanApiCaseService; private TestPlanApiCaseService testPlanApiCaseService;
@Resource @Resource
private TestPlanManagementService testPlanManagementService;
@Resource
private TestPlanService testPlanService; private TestPlanService testPlanService;
@PostMapping(value = "/sort")
@Operation(summary = "测试计划功能用例-功能用例拖拽排序")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
public TestPlanOperationResponse sortNode(@Validated @RequestBody ResourceSortRequest request) {
testPlanManagementService.checkModuleIsOpen(request.getTestCollectionId(), TestPlanResourceConfig.CHECK_TYPE_TEST_PLAN, Collections.singletonList(TestPlanResourceConfig.CONFIG_TEST_PLAN_FUNCTIONAL_CASE));
return testPlanApiCaseService.sortNode(request, new LogInsertModule(SessionUtils.getUserId(), "/test-plan/api/case/sort", HttpMethodConstants.POST.name()));
}
@PostMapping("/page") @PostMapping("/page")
@Operation(summary = "测试计划-已关联接口用例列表分页查询") @Operation(summary = "测试计划-已关联接口用例列表分页查询")

View File

@ -1,11 +1,16 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.plan.domain.TestPlan; import io.metersphere.plan.domain.TestPlan;
import io.metersphere.plan.domain.TestPlanCollection;
import io.metersphere.plan.domain.TestPlanCollectionExample;
import io.metersphere.plan.domain.TestPlanConfig;
import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest; import io.metersphere.plan.dto.request.TestPlanBatchExecuteRequest;
import io.metersphere.plan.dto.request.TestPlanExecuteRequest; import io.metersphere.plan.dto.request.TestPlanExecuteRequest;
import io.metersphere.plan.enums.TestPlanExecuteQueueType; import io.metersphere.plan.mapper.TestPlanCollectionMapper;
import io.metersphere.plan.mapper.TestPlanConfigMapper;
import io.metersphere.plan.mapper.TestPlanMapper; import io.metersphere.plan.mapper.TestPlanMapper;
import io.metersphere.sdk.constants.ApiBatchRunMode; import io.metersphere.sdk.constants.ApiBatchRunMode;
import io.metersphere.sdk.constants.CaseType;
import io.metersphere.sdk.constants.TestPlanConstants; import io.metersphere.sdk.constants.TestPlanConstants;
import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue; import io.metersphere.sdk.dto.queue.TestPlanExecutionQueue;
import io.metersphere.sdk.exception.MSException; import io.metersphere.sdk.exception.MSException;
@ -29,73 +34,41 @@ public class TestPlanExecuteService {
@Resource @Resource
private TestPlanMapper testPlanMapper; private TestPlanMapper testPlanMapper;
@Resource @Resource
private TestPlanConfigMapper testPlanConfigMapper;
@Resource
private TestPlanService testPlanService; private TestPlanService testPlanService;
@Resource
private TestPlanCollectionMapper testPlanCollectionMapper;
@Resource @Resource
private RedisTemplate<String, String> redisTemplate; private RedisTemplate<String, String> redisTemplate;
public static final String QUEUE_PREFIX_TEST_PLAN = "test-plan-execute:"; public static final String QUEUE_PREFIX_TEST_PLAN_BATCH = "test-plan-batch-execute:";
public static final String QUEUE_PREFIX_TEST_PLAN_GROUP = "test-plan-group-execute:"; public static final String QUEUE_PREFIX_TEST_PLAN_GROUP = "test-plan-group-execute:";
public static final String QUEUE_PREFIX_TEST_COLLECTION = "test-collection-execute:"; public static final String QUEUE_PREFIX_TEST_PLAN_COLLECTION = "test-plan-collection-execute:";
public static final String QUEUE_PREFIX_TEST_CASE = "test-plan-collection-execute:";
public String executeTestPlan(TestPlan testPlan, String executionSource, String userId) {
//todo 查询执行配置,配置下一步的队列
return "报告ID";
}
/**
* 预执行执行测试计划
*/
private String prepareExecuteTestPlan(TestPlan testPlan, String parentQueueId, String runMode, String executionSource, String userId) {
if (testPlan == null || StringUtils.equalsIgnoreCase(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
throw new MSException("test_plan.error");
}
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
List<TestPlan> children = testPlanService.selectNotArchivedChildren(testPlan.getId());
long pos = 0;
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
for (TestPlan child : children) {
childrenQueue.add(
new TestPlanExecutionQueue(child.getGroupId(), parentQueueId, child.getId(), pos++, runMode, executionSource, IDGenerator.nextStr(), userId, System.currentTimeMillis())
);
}
if (StringUtils.equalsIgnoreCase(runMode, ApiBatchRunMode.SERIAL.name())) {
//串行
childrenQueue.forEach(childQueue -> {
redisTemplate.opsForList().rightPush(QUEUE_PREFIX_TEST_PLAN_GROUP + testPlan.getId(), JSON.toJSONString(childrenQueue));
});
executeNextTestPlanByGroupQueueId(testPlan.getId(), parentQueueId);
} else {
//并行
childrenQueue.forEach(childQueue -> {
executeTestPlan(testPlanMapper.selectByPrimaryKey(childQueue.getTestPlanId()), childQueue.getExecutionSource(), childQueue.getCreateUser());
});
}
return "";
} else {
return this.executeTestPlan(testPlan, executionSource, userId);
}
}
//单独执行测试计划
/** /**
* 单个执行测试计划 * 单个执行测试计划
*/ */
public String singleExecuteTestPlan(TestPlanExecuteRequest request, String userId) { public String singleExecuteTestPlan(TestPlanExecuteRequest request, String userId) {
return prepareExecuteTestPlan(testPlanMapper.selectByPrimaryKey(request.getExecuteId()), null, request.getRunMode(), request.getExecutionSource(), userId); TestPlanExecutionQueue executionQueue = new TestPlanExecutionQueue();
executionQueue.setSourceID(request.getExecuteId());
executionQueue.setRunMode(request.getRunMode());
executionQueue.setExecutionSource(request.getExecutionSource());
executionQueue.setCreateUser(userId);
executionQueue.setPrepareReportId(IDGenerator.nextStr());
return executeTestPlanOrGroup(executionQueue);
} }
/** //批量执行测试计划
* 批量执行测试计划
*/
public void batchExecuteTestPlan(TestPlanBatchExecuteRequest request, String userId) { public void batchExecuteTestPlan(TestPlanBatchExecuteRequest request, String userId) {
List<String> rightfulIds = testPlanService.selectRightfulIds(request.getExecuteIds()); List<String> rightfulIds = testPlanService.selectRightfulIds(request.getExecuteIds());
if (CollectionUtils.isNotEmpty(rightfulIds)) { if (CollectionUtils.isNotEmpty(rightfulIds)) {
String runMode = request.getRunMode(); String runMode = request.getRunMode();
String queueId = IDGenerator.nextStr(); String queueId = IDGenerator.nextStr();
String queueType = QUEUE_PREFIX_TEST_PLAN_BATCH;
long pos = 0; long pos = 0;
List<TestPlanExecutionQueue> testPlanExecutionQueues = new ArrayList<>(); List<TestPlanExecutionQueue> testPlanExecutionQueues = new ArrayList<>();
@ -103,70 +76,237 @@ public class TestPlanExecuteService {
for (String testPlanId : request.getExecuteIds()) { for (String testPlanId : request.getExecuteIds()) {
if (rightfulIds.contains(testPlanId)) { if (rightfulIds.contains(testPlanId)) {
testPlanExecutionQueues.add( testPlanExecutionQueues.add(
new TestPlanExecutionQueue(queueId, null, testPlanId, pos++, runMode, request.getExecutionSource(), IDGenerator.nextStr(), userId, System.currentTimeMillis()) new TestPlanExecutionQueue(
pos++,
userId,
System.currentTimeMillis(),
queueId,
queueType,
null,
null,
testPlanId,
runMode,
request.getExecutionSource(),
IDGenerator.nextStr(),
false
)
); );
} }
} }
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
redisTemplate.opsForList().rightPush(testPlanExecutionQueue.getQueueType() + testPlanExecutionQueue.getQueueId(), JSON.toJSONString(testPlanExecutionQueue));
});
if (StringUtils.equalsIgnoreCase(request.getRunMode(), ApiBatchRunMode.SERIAL.name())) { if (StringUtils.equalsIgnoreCase(request.getRunMode(), ApiBatchRunMode.SERIAL.name())) {
//串行 //串行
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> { TestPlanExecutionQueue nextQueue = this.getNextQueue(queueId, queueType);
redisTemplate.opsForList().rightPush(QUEUE_PREFIX_TEST_PLAN + queueId, JSON.toJSONString(testPlanExecutionQueue)); executeTestPlanOrGroup(nextQueue);
});
executeNextTestPlanByQueueId(queueId);
} else { } else {
//并行 //并行
testPlanExecutionQueues.forEach(testPlanExecutionQueue -> { testPlanExecutionQueues.forEach(testPlanExecutionQueue -> {
prepareExecuteTestPlan(testPlanMapper.selectByPrimaryKey(testPlanExecutionQueue.getTestPlanId()), executeTestPlanOrGroup(testPlanExecutionQueue);
null,
testPlanExecutionQueue.getRunMode(),
testPlanExecutionQueue.getExecutionSource(),
testPlanExecutionQueue.getCreateUser());
}); });
} }
} }
} }
//执行下一个测试计划组节点的测试计划 //执行测试计划组
private void executeNextTestPlanByGroupQueueId(String groupQueueId, String parentQueueId) { private String executeTestPlanOrGroup(TestPlanExecutionQueue executionQueue) {
TestPlanExecutionQueue nextQueue = getNextDetail(groupQueueId, QUEUE_PREFIX_TEST_PLAN_GROUP, TestPlanExecutionQueue.class); TestPlan testPlan = testPlanMapper.selectByPrimaryKey(executionQueue.getSourceID());
if (testPlan == null || StringUtils.equalsIgnoreCase(testPlan.getStatus(), TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED)) {
throw new MSException("test_plan.error");
}
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
List<TestPlan> children = testPlanService.selectNotArchivedChildren(testPlan.getId());
long pos = 0;
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
String queueId = IDGenerator.nextStr();
String queueType = QUEUE_PREFIX_TEST_PLAN_GROUP;
for (TestPlan child : children) {
childrenQueue.add(
new TestPlanExecutionQueue(
pos++,
executionQueue.getCreateUser(),
System.currentTimeMillis(),
queueId,
queueType,
executionQueue.getQueueId(),
executionQueue.getQueueType(),
child.getId(),
executionQueue.getRunMode(),
executionQueue.getExecutionSource(),
IDGenerator.nextStr(),
false
)
);
}
childrenQueue.forEach(childQueue -> {
redisTemplate.opsForList().rightPush(childQueue.getQueueType() + childQueue.getQueueId(), JSON.toJSONString(childQueue));
});
if (StringUtils.equalsIgnoreCase(executionQueue.getRunMode(), ApiBatchRunMode.SERIAL.name())) {
//串行
TestPlanExecutionQueue nextQueue = this.getNextQueue(queueId, queueType);
executeTestPlan(nextQueue);
} else {
//并行
childrenQueue.forEach(childQueue -> {
executeTestPlan(childQueue);
});
}
return executionQueue.getPrepareReportId();
} else {
return this.executeTestPlan(executionQueue);
}
}
//执行测试计划
public String executeTestPlan(TestPlanExecutionQueue executionQueue) {
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(executionQueue.getSourceID());
TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample();
testPlanCollectionExample.createCriteria().andTestPlanIdEqualTo(testPlan.getId());
testPlanCollectionExample.setOrderByClause("pos asc");
//过滤掉功能用例的测试集
List<TestPlanCollection> testPlanCollectionList = testPlanCollectionMapper.selectByExample(testPlanCollectionExample).stream().filter(
testPlanCollection -> !StringUtils.equalsIgnoreCase(testPlanCollection.getType(), CaseType.FUNCTIONAL_CASE.getKey())
).toList();
int pos = 0;
TestPlanConfig testPlanConfig = testPlanConfigMapper.selectByPrimaryKey(testPlan.getId());
String runMode = StringUtils.isBlank(testPlanConfig.getCaseRunMode()) ? ApiBatchRunMode.SERIAL.name() : testPlanConfig.getCaseRunMode();
String queueId = IDGenerator.nextStr();
String queueType = QUEUE_PREFIX_TEST_PLAN_COLLECTION;
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
for (TestPlanCollection collection : testPlanCollectionList) {
childrenQueue.add(
new TestPlanExecutionQueue(
pos++,
executionQueue.getCreateUser(),
System.currentTimeMillis(),
queueId,
queueType,
executionQueue.getQueueId(),
executionQueue.getQueueType(),
collection.getId(),
executionQueue.getRunMode(),
executionQueue.getExecutionSource(),
IDGenerator.nextStr(),
false)
);
}
childrenQueue.forEach(childQueue -> {
redisTemplate.opsForList().rightPush(childQueue.getQueueType() + childQueue.getQueueId(), JSON.toJSONString(childQueue));
});
// todo Song-cc 这里是否要生成测试计划报告并且记录测试计划里用例的执行信息
//开始根据测试计划集合执行测试用例
if (StringUtils.equalsIgnoreCase(runMode, ApiBatchRunMode.SERIAL.name())) {
//串行
TestPlanExecutionQueue nextQueue = this.getNextQueue(queueId, queueType);
this.executeByTestPlanCollection(nextQueue);
} else {
//并行
childrenQueue.forEach(childQueue -> {
this.executeByTestPlanCollection(childQueue);
});
}
return executionQueue.getPrepareReportId();
}
//执行测试集
private void executeByTestPlanCollection(TestPlanExecutionQueue executionQueue) {
TestPlanCollection parentCollection = testPlanCollectionMapper.selectByPrimaryKey(executionQueue.getParentQueueId());
TestPlanCollectionExample example = new TestPlanCollectionExample();
example.createCriteria().andParentIdEqualTo(executionQueue.getSourceID());
List<TestPlanCollection> childrenList = testPlanCollectionMapper.selectByExample(example);
int pos = 0;
List<TestPlanExecutionQueue> childrenQueue = new ArrayList<>();
String queueId = IDGenerator.nextStr();
String queueType = QUEUE_PREFIX_TEST_CASE;
for (TestPlanCollection collection : childrenList) {
childrenQueue.add(
new TestPlanExecutionQueue(
pos++,
executionQueue.getCreateUser(),
System.currentTimeMillis(),
queueId,
queueType,
executionQueue.getQueueId(),
executionQueue.getQueueType(),
collection.getId(),
executionQueue.getRunMode(),
executionQueue.getExecutionSource(),
IDGenerator.nextStr(),
false)
);
}
childrenQueue.forEach(childQueue -> {
redisTemplate.opsForList().rightPush(childQueue.getQueueType() + childQueue.getQueueId(), JSON.toJSONString(childQueue));
});
if (StringUtils.equalsIgnoreCase(parentCollection.getExecuteMethod(), ApiBatchRunMode.SERIAL.name())) {
//串行
TestPlanExecutionQueue nextQueue = this.getNextQueue(queueId, queueType);
this.executeCase(nextQueue);
} else {
//并行
childrenQueue.forEach(childQueue -> {
this.executeCase(childQueue);
});
}
}
// todo @Chen jianxing 执行用例
private void executeCase(TestPlanExecutionQueue testPlanExecutionQueue) {
}
//todo 测试用例执行完成中的某一条
private void TestCaseExecuteQueueFinish(String queueID, String queueType) {
/**
* 当队列全部执行完时nextQueue将不会再查到
* 此时如何调用父类队列的执行方式
*/
TestPlanExecutionQueue nextQueue = getNextQueue(queueID, queueType);
if (nextQueue != null) { if (nextQueue != null) {
try { try {
executeTestPlan(testPlanMapper.selectByPrimaryKey(nextQueue.getTestPlanId()), nextQueue.getExecutionSource(), nextQueue.getCreateUser()); executeCase(nextQueue);
} catch (Exception e) { } catch (Exception e) {
this.executeNextTestPlanByQueueId(groupQueueId); this.testPlanCollectionExecuteQueueFinish(nextQueue.getParentQueueId(), nextQueue.getParentQueueType());
} }
} else { } else {
// todo 测试计划组执行完成 // testPlanCollectionExecuteQueueFinish(queueID, queueType);
if (StringUtils.isNotEmpty(parentQueueId)) {
// 如果测试计划组是在批量执行时处理的继续进行批量执行队列里的下个节点
executeNextTestPlanByQueueId(parentQueueId);
}
} }
} }
//执行下一个批量执行节点的测试计划 //todo 测试集执行完成中的某一条
private void executeNextTestPlanByQueueId(String queueId) { private void testPlanCollectionExecuteQueueFinish(String queueID, String queueType) {
TestPlanExecutionQueue nextQueue = getNextDetail(queueId, QUEUE_PREFIX_TEST_PLAN, TestPlanExecutionQueue.class);
}
//todo 测试计划执行完成中的某一条
private void TestPlanGroupExecuteQueueFinish(String queueID, String queueType) {
}
//测试计划批量执行队列节点执行完成
private void batchTestPlanExecuteQueueFinish(String queueId, String queueType) {
TestPlanExecutionQueue nextQueue = getNextQueue(queueId, queueType);
if (nextQueue != null) { if (nextQueue != null) {
try { try {
prepareExecuteTestPlan( executeTestPlanOrGroup(nextQueue);
testPlanMapper.selectByPrimaryKey(nextQueue.getTestPlanId()),
queueId,
nextQueue.getRunMode(),
nextQueue.getExecutionSource(),
nextQueue.getCreateUser());
} catch (Exception e) { } catch (Exception e) {
this.executeNextTestPlanByQueueId(queueId); this.batchTestPlanExecuteQueueFinish(queueId, queueType);
} }
} }
} }
/** /**
* 获取下一个队列节点 * 获取下一个队列节点
*/ */
private <T> T getNextDetail(String queueId, String queueType, Class<T> formatClass) { private TestPlanExecutionQueue getNextQueue(String queueId, String queueType) {
String queueKey = this.genQueueKey(queueId, queueType); String queueKey = this.genQueueKey(queueId, queueType);
ListOperations<String, String> listOps = redisTemplate.opsForList(); ListOperations<String, String> listOps = redisTemplate.opsForList();
String queueDetail = listOps.leftPop(queueKey); String queueDetail = listOps.leftPop(queueKey);
@ -185,12 +325,14 @@ public class TestPlanExecuteService {
} }
if (StringUtils.isNotBlank(queueDetail)) { if (StringUtils.isNotBlank(queueDetail)) {
TestPlanExecutionQueue returnQueue = JSON.parseObject(queueDetail, TestPlanExecutionQueue.class);
Long size = getQueueSize(queueId); Long size = getQueueSize(queueId);
if (size == null || size == 0) { if (size == null || size == 0) {
returnQueue.setLastNode(true);
// 最后一个节点清理队列 // 最后一个节点清理队列
deleteQueue(queueKey); deleteQueue(queueKey);
} }
return JSON.parseObject(queueDetail, formatClass); return returnQueue;
} }
// 整体获取完清理队列 // 整体获取完清理队列
@ -209,14 +351,6 @@ public class TestPlanExecuteService {
//生成队列key //生成队列key
private String genQueueKey(String queueId, String queueType) { private String genQueueKey(String queueId, String queueType) {
String key = ""; return queueType + queueId;
if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_PLAN.name())) {
key = QUEUE_PREFIX_TEST_PLAN;
} else if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_PLAN_GROUP.name())) {
key = QUEUE_PREFIX_TEST_PLAN_GROUP;
} else if (StringUtils.equalsIgnoreCase(queueType, TestPlanExecuteQueueType.TEST_COLLECTION.name())) {
key = QUEUE_PREFIX_TEST_COLLECTION;
}
return key + queueId;
} }
} }

View File

@ -15,7 +15,9 @@ import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.api.utils.ApiDataUtils; import io.metersphere.api.utils.ApiDataUtils;
import io.metersphere.plan.constants.AssociateCaseType; import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.domain.TestPlanApiCase; import io.metersphere.plan.domain.TestPlanApiCase;
import io.metersphere.plan.domain.TestPlanApiCaseExample;
import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
import io.metersphere.plan.mapper.TestPlanApiCaseMapper; import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
import io.metersphere.plan.service.TestPlanApiCaseService; import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.project.mapper.ExtBaseProjectVersionMapper; import io.metersphere.project.mapper.ExtBaseProjectVersionMapper;
@ -26,6 +28,7 @@ import io.metersphere.sdk.util.CommonBeanFactory;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest; import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.controller.handler.ResultHolder;
import io.metersphere.system.dto.sdk.enums.MoveTypeEnum;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
@ -51,6 +54,7 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
public static final String API_CASE_DISASSOCIATE = "disassociate"; 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_DISASSOCIATE = "batch/disassociate";
public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "batch/update/executor"; public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "batch/update/executor";
private static final String URL_POST_RESOURCE_API_CASE_SORT = "/sort";
public static final String RUN = "run/{0}"; public static final String RUN = "run/{0}";
public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}"; public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}";
@ -109,6 +113,44 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
request.setTreeType("COLLECTION"); request.setTreeType("COLLECTION");
this.requestPostWithOkAndReturn(API_CASE_TREE_COUNT, request); this.requestPostWithOkAndReturn(API_CASE_TREE_COUNT, request);
this.testSort();
}
public void testSort() throws Exception {
TestPlanApiCaseExample testPlanApiCaseExample = new TestPlanApiCaseExample();
testPlanApiCaseExample.createCriteria().andTestPlanCollectionIdEqualTo("wxxx_2");
testPlanApiCaseExample.setOrderByClause("pos asc");
List<TestPlanApiCase> apiList = testPlanApiCaseMapper.selectByExample(testPlanApiCaseExample);
//最后一个移动到第一位之前
ResourceSortRequest request = new ResourceSortRequest();
request.setTestCollectionId("wxxx_2");
request.setProjectId("wxx_1234");
request.setMoveId(apiList.getLast().getId());
request.setTargetId(apiList.getFirst().getId());
request.setMoveMode(MoveTypeEnum.AFTER.name());
MvcResult result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_CASE_SORT, request);
ResultHolder resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
TestPlanOperationResponse response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
Assertions.assertEquals(response.getOperationCount(), 1);
apiList = testPlanApiCaseMapper.selectByExample(testPlanApiCaseExample);
Assertions.assertEquals(apiList.get(0).getId(), request.getMoveId());
Assertions.assertEquals(apiList.get(1).getId(), request.getTargetId());
//将这时的第30个放到第一位之后
request.setTargetId(apiList.getLast().getId());
request.setMoveId(apiList.getFirst().getId());
request.setMoveMode(MoveTypeEnum.BEFORE.name());
result = this.requestPostWithOkAndReturn(URL_POST_RESOURCE_API_CASE_SORT, request);
resultHolder = JSON.parseObject(result.getResponse().getContentAsString(StandardCharsets.UTF_8), ResultHolder.class);
response = JSON.parseObject(JSON.toJSONString(resultHolder.getData()), TestPlanOperationResponse.class);
Assertions.assertEquals(response.getOperationCount(), 1);
apiList = testPlanApiCaseMapper.selectByExample(testPlanApiCaseExample);
Assertions.assertEquals(apiList.get(0).getId(), request.getTargetId());
Assertions.assertEquals(apiList.get(1).getId(), request.getMoveId());
} }
@Test @Test

View File

@ -30,9 +30,9 @@ VALUES
INSERT INTO `test_plan_api_case`(`id`, `test_plan_id`, `api_case_id`, `environment_id`, `last_exec_result`, `last_exec_report_id`, `execute_user`, `create_time`, `create_user`, `pos`, `test_plan_collection_id`, `last_exec_time`) INSERT INTO `test_plan_api_case`(`id`, `test_plan_id`, `api_case_id`, `environment_id`, `last_exec_result`, `last_exec_report_id`, `execute_user`, `create_time`, `create_user`, `pos`, `test_plan_collection_id`, `last_exec_time`)
VALUES VALUES
('wxxx_1', 'wxxx_1', 'wxxx_api_case_1', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'wxxx_2', 1716370415311), ('wxxx_1', 'wxxx_1', 'wxxx_api_case_1', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 4096, 'wxxx_2', 1716370415311),
('wxxx_2', 'wxxx_1', 'wxxx_api_case_2', '123', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'wxxx_3', 1716370415311), ('wxxx_2', 'wxxx_1', 'wxxx_api_case_2', '123', NULL, NULL, 'admin', 1716370415311, 'admin', 4096, 'wxxx_3', 1716370415311),
('wxxx_3', 'wxxx_2', 'wxxx_api_case_3', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'wxxx_2', 1716370415311); ('wxxx_3', 'wxxx_2', 'wxxx_api_case_3', '1', NULL, NULL, 'admin', 1716370415311, 'admin', 8192, 'wxxx_2', 1716370415311);
INSERT INTO `test_plan_collection`(`id`, `test_plan_id`, `name`, `type`, `environment_id`, `test_resource_pool_id`, `pos`, `create_user`, `create_time`, `parent_id`) INSERT INTO `test_plan_collection`(`id`, `test_plan_id`, `name`, `type`, `environment_id`, `test_resource_pool_id`, `pos`, `create_user`, `create_time`, `parent_id`)
VALUES VALUES