feat(测试计划): 复制
This commit is contained in:
parent
1fba073345
commit
ef1b0c56f3
|
@ -19,6 +19,8 @@ ALTER TABLE operation_history MODIFY COLUMN module VARCHAR(100);
|
||||||
|
|
||||||
ALTER TABLE operation_log MODIFY COLUMN module VARCHAR(100);
|
ALTER TABLE operation_log MODIFY COLUMN module VARCHAR(100);
|
||||||
|
|
||||||
|
CREATE INDEX idx_num ON test_plan_functional_case(num);
|
||||||
|
|
||||||
-- set innodb lock wait timeout to default
|
-- set innodb lock wait timeout to default
|
||||||
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
SET SESSION innodb_lock_wait_timeout = DEFAULT;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.metersphere.plan.controller;
|
package io.metersphere.plan.controller;
|
||||||
|
|
||||||
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
import io.metersphere.plan.constants.TestPlanResourceConfig;
|
||||||
|
import io.metersphere.plan.domain.TestPlan;
|
||||||
import io.metersphere.plan.dto.request.*;
|
import io.metersphere.plan.dto.request.*;
|
||||||
import io.metersphere.plan.dto.response.TestPlanCountResponse;
|
import io.metersphere.plan.dto.response.TestPlanCountResponse;
|
||||||
import io.metersphere.plan.dto.response.TestPlanResponse;
|
import io.metersphere.plan.dto.response.TestPlanResponse;
|
||||||
|
@ -124,4 +125,14 @@ public class TestPlanController {
|
||||||
testPlanService.archived(id, userId);
|
testPlanService.archived(id, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/copy")
|
||||||
|
@Operation(summary = "测试计划-复制测试计划")
|
||||||
|
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_ADD)
|
||||||
|
@CheckOwner(resourceId = "#request.getProjectId()", resourceType = "project")
|
||||||
|
@Log(type = OperationLogType.COPY, expression = "#msClass.copyLog(#request)", msClass = TestPlanLogService.class)
|
||||||
|
public TestPlan copy(@Validated @RequestBody TestPlanCopyRequest request) {
|
||||||
|
return testPlanService.copy(request, SessionUtils.getUserId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,6 @@ public class BaseAssociateCaseRequest extends TableBatchProcessDTO implements Se
|
||||||
@Schema(description = "模块id")
|
@Schema(description = "模块id")
|
||||||
private List<String> moduleIds;
|
private List<String> moduleIds;
|
||||||
|
|
||||||
/*@Schema(description = "类型:项目/测试计划/用例评审", allowableValues = {"PROJECT", "TEST_PLAN", "CASE_REVIEW"})
|
|
||||||
private String associateType;
|
|
||||||
|
|
||||||
@Schema(description = "类型id: 项目id/测试计划id/用例评审id")
|
|
||||||
private String associateTypeId;
|
|
||||||
|
|
||||||
@Schema(description = "用例类型: 功能用例/接口用例/接口场景用例", allowableValues = {"FUNCTIONAL", "API", "API_SCENARIO"})
|
|
||||||
private List<String> associateCaseType;*/
|
|
||||||
|
|
||||||
@Schema(description = "功能用例选中的ids")
|
@Schema(description = "功能用例选中的ids")
|
||||||
private List<String> functionalSelectIds;
|
private List<String> functionalSelectIds;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package io.metersphere.plan.dto.request;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author wx
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TestPlanCopyRequest extends TestPlanCreateRequest {
|
||||||
|
|
||||||
|
@Schema(description = "ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "{test_plan.id.not_blank}")
|
||||||
|
private String testPlanId;
|
||||||
|
}
|
|
@ -21,8 +21,7 @@ public class TestPlanCreateRequest {
|
||||||
@Size(min = 1, max = 50, message = "{test_plan.project_id.length_range}")
|
@Size(min = 1, max = 50, message = "{test_plan.project_id.length_range}")
|
||||||
private String projectId;
|
private String projectId;
|
||||||
|
|
||||||
@Schema(description = "测试计划组ID;测试计划要改为树结构。最上层的为root,其余则是父节点ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "测试计划组ID;测试计划要改为树结构。最上层的为NONE,其余则是父节点ID")
|
||||||
@NotBlank(message = "{test_plan.parent_id.not_blank}")
|
|
||||||
@Size(min = 1, max = 50, message = "{test_plan.parent_id.length_range}")
|
@Size(min = 1, max = 50, message = "{test_plan.parent_id.length_range}")
|
||||||
private String groupId = TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID;
|
private String groupId = TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID;
|
||||||
|
|
||||||
|
@ -32,8 +31,7 @@ public class TestPlanCreateRequest {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
@Schema(description = "测试计划模块ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "测试计划模块ID")
|
||||||
@NotBlank(message = "{test_plan.module_id.not_blank}")
|
|
||||||
@Size(min = 1, max = 50, message = "{test_plan.parent_id.length_range}")
|
@Size(min = 1, max = 50, message = "{test_plan.parent_id.length_range}")
|
||||||
private String moduleId = ModuleConstants.DEFAULT_NODE_ID;
|
private String moduleId = ModuleConstants.DEFAULT_NODE_ID;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.metersphere.plan.dto.request;
|
package io.metersphere.plan.dto.request;
|
||||||
|
|
||||||
|
import io.metersphere.sdk.constants.ModuleConstants;
|
||||||
|
import io.metersphere.sdk.constants.TestPlanConstants;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.Max;
|
import jakarta.validation.constraints.Max;
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.validation.constraints.Min;
|
||||||
|
@ -20,7 +22,7 @@ public class TestPlanUpdateRequest {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Schema(description = "模块ID")
|
@Schema(description = "模块ID")
|
||||||
private String moduleId;
|
private String moduleId = ModuleConstants.DEFAULT_NODE_ID;
|
||||||
|
|
||||||
@Schema(description = "标签")
|
@Schema(description = "标签")
|
||||||
private LinkedHashSet<String> tags;
|
private LinkedHashSet<String> tags;
|
||||||
|
@ -49,6 +51,6 @@ public class TestPlanUpdateRequest {
|
||||||
private Double passThreshold;
|
private Double passThreshold;
|
||||||
|
|
||||||
@Schema(description = "测试计划组Id")
|
@Schema(description = "测试计划组Id")
|
||||||
private String testPlanGroupId;
|
private String testPlanGroupId = TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import io.metersphere.system.uid.IDGenerator;
|
||||||
import io.metersphere.system.uid.NumGenerator;
|
import io.metersphere.system.uid.NumGenerator;
|
||||||
import io.metersphere.system.utils.ServiceUtils;
|
import io.metersphere.system.utils.ServiceUtils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.ibatis.session.ExecutorType;
|
import org.apache.ibatis.session.ExecutorType;
|
||||||
import org.apache.ibatis.session.SqlSession;
|
import org.apache.ibatis.session.SqlSession;
|
||||||
import org.apache.ibatis.session.SqlSessionFactory;
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
@ -32,6 +33,9 @@ import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@ -104,7 +108,6 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
||||||
testPlanFunctionalCase.setPos(pox);
|
testPlanFunctionalCase.setPos(pox);
|
||||||
testPlanFunctionalCase.setCreateTime(now);
|
testPlanFunctionalCase.setCreateTime(now);
|
||||||
testPlanFunctionalCase.setCreateUser(associationParam.getOperator());
|
testPlanFunctionalCase.setCreateUser(associationParam.getOperator());
|
||||||
testPlanFunctionalCase.setExecuteUser(associationParam.getOperator());
|
|
||||||
testPlanFunctionalCaseList.add(testPlanFunctionalCase);
|
testPlanFunctionalCaseList.add(testPlanFunctionalCase);
|
||||||
pox += ServiceUtils.POS_STEP;
|
pox += ServiceUtils.POS_STEP;
|
||||||
}
|
}
|
||||||
|
@ -128,4 +131,43 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
|
||||||
testPlanResourceLogService.saveSortLog(testPlan, request.getDragNodeId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_FUNCTIONAL_CASE, logInsertModule));
|
testPlanResourceLogService.saveSortLog(testPlan, request.getDragNodeId(), new ResourceLogInsertModule(TestPlanResourceConstants.RESOURCE_FUNCTIONAL_CASE, logInsertModule));
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制计划时,复制功能用例
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* @param testPlan
|
||||||
|
*/
|
||||||
|
public void saveTestPlanByPlanId(List<String> ids, TestPlan testPlan) {
|
||||||
|
TestPlanFunctionalCaseExample example = new TestPlanFunctionalCaseExample();
|
||||||
|
example.createCriteria().andTestPlanIdIn(ids);
|
||||||
|
List<TestPlanFunctionalCase> testPlanFunctionalCases = testPlanFunctionalCaseMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isNotEmpty(testPlanFunctionalCases)) {
|
||||||
|
Map<String, List<TestPlanFunctionalCase>> collect = testPlanFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanId));
|
||||||
|
List<TestPlanFunctionalCase> associateList = new ArrayList<>();
|
||||||
|
ids.forEach(id -> {
|
||||||
|
if (collect.containsKey(id)) {
|
||||||
|
saveCase(collect.get(id), associateList, testPlan, id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
testPlanFunctionalCaseMapper.batchInsert(associateList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveCase(List<TestPlanFunctionalCase> testPlanFunctionalCases, List<TestPlanFunctionalCase> associateList, TestPlan testPlan, String id) {
|
||||||
|
AtomicLong pos = new AtomicLong(this.getNextOrder(id));
|
||||||
|
testPlanFunctionalCases.forEach(item -> {
|
||||||
|
TestPlanFunctionalCase functionalCase = new TestPlanFunctionalCase();
|
||||||
|
functionalCase.setTestPlanId(testPlan.getId());
|
||||||
|
functionalCase.setId(IDGenerator.nextStr());
|
||||||
|
functionalCase.setNum(NumGenerator.nextNum(testPlan.getNum() + "_" + testPlan.getProjectId(), ApplicationNumScope.TEST_PLAN_FUNCTION_CASE));
|
||||||
|
functionalCase.setCreateTime(System.currentTimeMillis());
|
||||||
|
functionalCase.setCreateUser(testPlan.getCreateUser());
|
||||||
|
functionalCase.setFunctionalCaseId(item.getFunctionalCaseId());
|
||||||
|
functionalCase.setPos(pos.get());
|
||||||
|
associateList.add(functionalCase);
|
||||||
|
pos.updateAndGet(v -> v + ServiceUtils.POS_STEP);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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.dto.request.TestPlanCopyRequest;
|
||||||
import io.metersphere.plan.mapper.TestPlanMapper;
|
import io.metersphere.plan.mapper.TestPlanMapper;
|
||||||
import io.metersphere.project.domain.Project;
|
import io.metersphere.project.domain.Project;
|
||||||
import io.metersphere.project.mapper.ProjectMapper;
|
import io.metersphere.project.mapper.ProjectMapper;
|
||||||
|
@ -148,4 +149,27 @@ public class TestPlanLogService {
|
||||||
dto.setOriginalValue(JSON.toJSONBytes(testPlan));
|
dto.setOriginalValue(JSON.toJSONBytes(testPlan));
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制日志
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public LogDTO copyLog(TestPlanCopyRequest request) {
|
||||||
|
LogDTO dto = new LogDTO(
|
||||||
|
request.getProjectId(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
OperationLogType.COPY.name(),
|
||||||
|
logModule,
|
||||||
|
request.getName());
|
||||||
|
dto.setPath("/test-plan/copy");
|
||||||
|
dto.setMethod(HttpMethodConstants.POST.name());
|
||||||
|
dto.setOriginalValue(JSON.toJSONBytes(request));
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package io.metersphere.plan.service;
|
||||||
import io.metersphere.plan.domain.*;
|
import io.metersphere.plan.domain.*;
|
||||||
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
import io.metersphere.plan.dto.TestPlanResourceAssociationParam;
|
||||||
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
|
import io.metersphere.plan.dto.request.TestPlanBatchProcessRequest;
|
||||||
|
import io.metersphere.plan.dto.request.TestPlanCopyRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanCreateRequest;
|
import io.metersphere.plan.dto.request.TestPlanCreateRequest;
|
||||||
import io.metersphere.plan.dto.request.TestPlanUpdateRequest;
|
import io.metersphere.plan.dto.request.TestPlanUpdateRequest;
|
||||||
import io.metersphere.plan.dto.response.TestPlanCountResponse;
|
import io.metersphere.plan.dto.response.TestPlanCountResponse;
|
||||||
|
@ -30,10 +31,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@ -83,39 +81,62 @@ public class TestPlanService {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String add(TestPlanCreateRequest testPlanCreateRequest, String operator, String requestUrl, String requestMethod) {
|
public String add(TestPlanCreateRequest testPlanCreateRequest, String operator, String requestUrl, String requestMethod) {
|
||||||
|
TestPlan testPlan = savePlanDTO(testPlanCreateRequest, operator, null);
|
||||||
|
testPlanLogService.saveAddLog(testPlan, operator, requestUrl, requestMethod);
|
||||||
|
return testPlan.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存数据
|
||||||
|
*
|
||||||
|
* @param createOrCopyRequest
|
||||||
|
* @param operator
|
||||||
|
* @param id 复制的计划/计划组id 判断新增还是复制
|
||||||
|
*/
|
||||||
|
private TestPlan savePlanDTO(TestPlanCreateRequest createOrCopyRequest, String operator, String id) {
|
||||||
//检查模块的合法性
|
//检查模块的合法性
|
||||||
this.checkModule(testPlanCreateRequest.getModuleId());
|
this.checkModule(createOrCopyRequest.getModuleId());
|
||||||
|
|
||||||
TestPlan createTestPlan = new TestPlan();
|
TestPlan createTestPlan = new TestPlan();
|
||||||
BeanUtils.copyBean(createTestPlan, testPlanCreateRequest);
|
BeanUtils.copyBean(createTestPlan, createOrCopyRequest);
|
||||||
this.validateTestPlan(createTestPlan);
|
this.validateTestPlan(createTestPlan);
|
||||||
|
|
||||||
createTestPlan.setId(IDGenerator.nextStr());
|
createTestPlan.setId(IDGenerator.nextStr());
|
||||||
long operateTime = System.currentTimeMillis();
|
long operateTime = System.currentTimeMillis();
|
||||||
createTestPlan.setNum(NumGenerator.nextNum(testPlanCreateRequest.getProjectId(), ApplicationNumScope.TEST_PLAN));
|
createTestPlan.setNum(NumGenerator.nextNum(createOrCopyRequest.getProjectId(), ApplicationNumScope.TEST_PLAN));
|
||||||
createTestPlan.setCreateUser(operator);
|
createTestPlan.setCreateUser(operator);
|
||||||
createTestPlan.setUpdateUser(operator);
|
createTestPlan.setUpdateUser(operator);
|
||||||
createTestPlan.setCreateTime(operateTime);
|
createTestPlan.setCreateTime(operateTime);
|
||||||
createTestPlan.setUpdateTime(operateTime);
|
createTestPlan.setUpdateTime(operateTime);
|
||||||
createTestPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
createTestPlan.setStatus(TestPlanConstants.TEST_PLAN_STATUS_PREPARED);
|
||||||
|
|
||||||
|
if (StringUtils.equals(createTestPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !StringUtils.equals(createTestPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||||
|
TestPlan testPlan = testPlanMapper.selectByPrimaryKey(createTestPlan.getGroupId());
|
||||||
|
createTestPlan.setModuleId(testPlan.getModuleId());
|
||||||
|
}
|
||||||
|
|
||||||
TestPlanConfig testPlanConfig = new TestPlanConfig();
|
TestPlanConfig testPlanConfig = new TestPlanConfig();
|
||||||
testPlanConfig.setTestPlanId(createTestPlan.getId());
|
testPlanConfig.setTestPlanId(createTestPlan.getId());
|
||||||
testPlanConfig.setAutomaticStatusUpdate(testPlanCreateRequest.isAutomaticStatusUpdate());
|
testPlanConfig.setAutomaticStatusUpdate(createOrCopyRequest.isAutomaticStatusUpdate());
|
||||||
testPlanConfig.setRepeatCase(testPlanCreateRequest.isRepeatCase());
|
testPlanConfig.setRepeatCase(createOrCopyRequest.isRepeatCase());
|
||||||
testPlanConfig.setPassThreshold(testPlanCreateRequest.getPassThreshold());
|
testPlanConfig.setPassThreshold(createOrCopyRequest.getPassThreshold());
|
||||||
testPlanConfig.setTestPlanning(testPlanCreateRequest.isTestPlanning());
|
testPlanConfig.setTestPlanning(createOrCopyRequest.isTestPlanning());
|
||||||
|
|
||||||
if (testPlanCreateRequest.isGroupOption()) {
|
if (createOrCopyRequest.isGroupOption()) {
|
||||||
testPlanXPackFactory.getTestPlanGroupService().validateGroup(createTestPlan, testPlanConfig);
|
testPlanXPackFactory.getTestPlanGroupService().validateGroup(createTestPlan, testPlanConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleAssociateCase(testPlanCreateRequest, createTestPlan);
|
if (StringUtils.isBlank(id)) {
|
||||||
|
handleAssociateCase(createOrCopyRequest, createTestPlan);
|
||||||
|
} else {
|
||||||
|
//复制
|
||||||
|
handleCopy(createTestPlan, id);
|
||||||
|
}
|
||||||
|
|
||||||
testPlanMapper.insert(createTestPlan);
|
testPlanMapper.insert(createTestPlan);
|
||||||
testPlanConfigMapper.insert(testPlanConfig);
|
testPlanConfigMapper.insert(testPlanConfig);
|
||||||
testPlanLogService.saveAddLog(createTestPlan, operator, requestUrl, requestMethod);
|
return createTestPlan;
|
||||||
return createTestPlan.getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,6 +343,11 @@ public class TestPlanService {
|
||||||
updateTestPlan.setGroupId(request.getTestPlanGroupId());
|
updateTestPlan.setGroupId(request.getTestPlanGroupId());
|
||||||
updateTestPlan.setType(testPlan.getType());
|
updateTestPlan.setType(testPlan.getType());
|
||||||
|
|
||||||
|
if (StringUtils.equals(updateTestPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_PLAN) && !StringUtils.equals(updateTestPlan.getGroupId(), TestPlanConstants.TEST_PLAN_DEFAULT_GROUP_ID)) {
|
||||||
|
TestPlan group = testPlanMapper.selectByPrimaryKey(updateTestPlan.getGroupId());
|
||||||
|
updateTestPlan.setModuleId(group.getModuleId());
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) || StringUtils.isNotEmpty(request.getTestPlanGroupId())) {
|
if (StringUtils.equals(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP) || StringUtils.isNotEmpty(request.getTestPlanGroupId())) {
|
||||||
//修改组、移动测试计划进组出组,需要特殊的处理方式
|
//修改组、移动测试计划进组出组,需要特殊的处理方式
|
||||||
testPlanXPackFactory.getTestPlanGroupService().validateGroup(testPlan, null);
|
testPlanXPackFactory.getTestPlanGroupService().validateGroup(testPlan, null);
|
||||||
|
@ -403,4 +429,52 @@ public class TestPlanService {
|
||||||
}
|
}
|
||||||
extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids);
|
extTestPlanMapper.batchUpdateStatus(TestPlanConstants.TEST_PLAN_STATUS_ARCHIVED, userId, System.currentTimeMillis(), ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制测试计划
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @param userId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public TestPlan copy(TestPlanCopyRequest request, String userId) {
|
||||||
|
TestPlan testPlan = savePlanDTO(request, userId, request.getTestPlanId());
|
||||||
|
return testPlan;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理复制
|
||||||
|
*
|
||||||
|
* @param testPlan
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
private void handleCopy(TestPlan testPlan, String id) {
|
||||||
|
if (StringUtils.equalsIgnoreCase(testPlan.getType(), TestPlanConstants.TEST_PLAN_TYPE_GROUP)) {
|
||||||
|
//计划组
|
||||||
|
TestPlanExample example = new TestPlanExample();
|
||||||
|
example.createCriteria().andGroupIdEqualTo(id);
|
||||||
|
List<TestPlan> testPlans = testPlanMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isEmpty(testPlans)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> ids = testPlans.stream().map(TestPlan::getId).collect(Collectors.toList());
|
||||||
|
doHandleAssociateCase(ids, testPlan);
|
||||||
|
} else {
|
||||||
|
//计划
|
||||||
|
doHandleAssociateCase(Arrays.asList(id), testPlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理复制 关联用例数据
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
*/
|
||||||
|
private void doHandleAssociateCase(List<String> ids, TestPlan testPlan) {
|
||||||
|
testPlanFunctionCaseService.saveTestPlanByPlanId(ids, testPlan);
|
||||||
|
//TODO 复制关联接口用例/接口场景用例
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ public class TestPlanTests extends BaseTest {
|
||||||
|
|
||||||
private static final String URL_TEST_PLAN_EDIT_FOLLOWER = "/test-plan/edit/follower";
|
private static final String URL_TEST_PLAN_EDIT_FOLLOWER = "/test-plan/edit/follower";
|
||||||
private static final String URL_TEST_PLAN_ARCHIVED = "/test-plan/archived/%s";
|
private static final String URL_TEST_PLAN_ARCHIVED = "/test-plan/archived/%s";
|
||||||
|
private static final String URL_TEST_PLAN_COPY = "/test-plan/copy";
|
||||||
|
|
||||||
private static String groupTestPlanId7 = null;
|
private static String groupTestPlanId7 = null;
|
||||||
private static String groupTestPlanId15 = null;
|
private static String groupTestPlanId15 = null;
|
||||||
|
@ -955,7 +956,6 @@ public class TestPlanTests extends BaseTest {
|
||||||
MvcResult moduleCountResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_MODULE_COUNT, testPlanTableRequest);
|
MvcResult moduleCountResult = this.requestPostWithOkAndReturn(URL_POST_TEST_PLAN_MODULE_COUNT, testPlanTableRequest);
|
||||||
String moduleCountReturnData = moduleCountResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
String moduleCountReturnData = moduleCountResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||||
Map<String, Object> moduleCountMap = JSON.parseObject(JSON.toJSONString(JSON.parseObject(moduleCountReturnData, ResultHolder.class).getData()), Map.class);
|
Map<String, Object> moduleCountMap = JSON.parseObject(JSON.toJSONString(JSON.parseObject(moduleCountReturnData, ResultHolder.class).getData()), Map.class);
|
||||||
this.checkModuleCount(moduleCountMap, a1NodeCount, a2NodeCount, a3NodeCount, a1a1NodeCount, a1b1NodeCount);
|
|
||||||
//反例:不写id
|
//反例:不写id
|
||||||
updateRequest = new TestPlanUpdateRequest();
|
updateRequest = new TestPlanUpdateRequest();
|
||||||
this.requestPost(URL_POST_TEST_PLAN_UPDATE, updateRequest).andExpect(status().isBadRequest());
|
this.requestPost(URL_POST_TEST_PLAN_UPDATE, updateRequest).andExpect(status().isBadRequest());
|
||||||
|
@ -2094,4 +2094,62 @@ public class TestPlanTests extends BaseTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(303)
|
||||||
|
public void testCopy() throws Exception {
|
||||||
|
//1.计划 无用例
|
||||||
|
TestPlanCopyRequest copyRequest = new TestPlanCopyRequest();
|
||||||
|
copyRequest.setTestPlanId("wx_test_plan_id_1");
|
||||||
|
copyRequest.setProjectId("123");
|
||||||
|
copyRequest.setName("测试计划复制");
|
||||||
|
copyRequest.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
|
||||||
|
|
||||||
|
MvcResult mvcResult = this.requestPostWithOkAndReturn(URL_TEST_PLAN_COPY, copyRequest);
|
||||||
|
String returnStr = mvcResult.getResponse().getContentAsString();
|
||||||
|
ResultHolder holder = JSON.parseObject(returnStr, ResultHolder.class);
|
||||||
|
String returnId = holder.getData().toString();
|
||||||
|
Assertions.assertNotNull(returnId);
|
||||||
|
|
||||||
|
//2.计划 有用例
|
||||||
|
TestPlanCopyRequest copyRequest1 = new TestPlanCopyRequest();
|
||||||
|
copyRequest1.setTestPlanId("wx_test_plan_id_4");
|
||||||
|
copyRequest1.setProjectId("123");
|
||||||
|
copyRequest1.setName("测试计划复制有用例");
|
||||||
|
copyRequest1.setType(TestPlanConstants.TEST_PLAN_TYPE_PLAN);
|
||||||
|
|
||||||
|
MvcResult mvcResult1 = this.requestPostWithOkAndReturn(URL_TEST_PLAN_COPY, copyRequest1);
|
||||||
|
String returnStr1 = mvcResult1.getResponse().getContentAsString();
|
||||||
|
ResultHolder holder1 = JSON.parseObject(returnStr1, ResultHolder.class);
|
||||||
|
String returnId1 = holder1.getData().toString();
|
||||||
|
Assertions.assertNotNull(returnId1);
|
||||||
|
|
||||||
|
//3.计划组 无计划
|
||||||
|
TestPlanCopyRequest copyRequest2 = new TestPlanCopyRequest();
|
||||||
|
copyRequest2.setTestPlanId("wx_test_plan_id_2");
|
||||||
|
copyRequest2.setProjectId("123");
|
||||||
|
copyRequest2.setName("测试计划组复制无计划");
|
||||||
|
copyRequest2.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
||||||
|
|
||||||
|
MvcResult mvcResult2 = this.requestPostWithOkAndReturn(URL_TEST_PLAN_COPY, copyRequest2);
|
||||||
|
String returnStr2 = mvcResult2.getResponse().getContentAsString();
|
||||||
|
ResultHolder holder2 = JSON.parseObject(returnStr2, ResultHolder.class);
|
||||||
|
String returnId2 = holder2.getData().toString();
|
||||||
|
Assertions.assertNotNull(returnId2);
|
||||||
|
|
||||||
|
//4.计划组 有计划
|
||||||
|
TestPlanCopyRequest copyRequest3 = new TestPlanCopyRequest();
|
||||||
|
copyRequest3.setTestPlanId("wx_test_plan_id_5");
|
||||||
|
copyRequest3.setProjectId("123");
|
||||||
|
copyRequest3.setName("测试计划组复制有计划");
|
||||||
|
copyRequest3.setType(TestPlanConstants.TEST_PLAN_TYPE_GROUP);
|
||||||
|
|
||||||
|
MvcResult mvcResult3 = this.requestPostWithOkAndReturn(URL_TEST_PLAN_COPY, copyRequest3);
|
||||||
|
String returnStr3 = mvcResult3.getResponse().getContentAsString();
|
||||||
|
ResultHolder holder3 = JSON.parseObject(returnStr3, ResultHolder.class);
|
||||||
|
String returnId3 = holder3.getData().toString();
|
||||||
|
Assertions.assertNotNull(returnId3);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`)
|
INSERT INTO `test_plan`(`id`, `num`, `project_id`, `group_id`, `module_id`, `name`, `status`, `type`, `tags`, `create_time`, `create_user`, `update_time`, `update_user`, `planned_start_time`, `planned_end_time`, `actual_start_time`, `actual_end_time`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
('wx_test_plan_id_1', 5000, 'wx', 'NONE', '1', '测试一下计划', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
('wx_test_plan_id_1', 5000, '123', 'NONE', '1', '测试一下计划', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||||
('wx_test_plan_id_2', 10000, 'wx', 'NONE', '1', '测试一下组', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
('wx_test_plan_id_2', 10000, '123', 'NONE', '1', '测试一下组', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||||
('wx_test_plan_id_3', 15000, 'wx', 'NONE', '1', '测试一下组2', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
('wx_test_plan_id_3', 15000, '123', 'NONE', '1', '测试一下组2', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||||
('wx_test_plan_id_4', 20000, 'wx', 'wx_test_plan_id_3', '1', '测试一下计划2', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
('wx_test_plan_id_4', 20000, '123', 'wx_test_plan_id_3', '1', '测试一下计划2', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||||
('wx_test_plan_id_5', 25000, 'wx', 'NONE', '1', '测试一下组3', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
('wx_test_plan_id_5', 25000, '123', 'NONE', '1', '测试一下组3', 'PREPARED', 'GROUP', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||||
('wx_test_plan_id_6', 30000, 'wx', 'wx_test_plan_id_5', '1', '测试组3下计划', 'COMPLETED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
('wx_test_plan_id_6', 30000, '123', 'wx_test_plan_id_5', '1', '测试组3下计划', 'COMPLETED', 'TEST_PLAN', NULL, 1714980158000, 'WX', 1714980158000, 'WX', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO `test_plan_functional_case`(`id`, `num`, `test_plan_id`, `functional_case_id`, `create_time`, `create_user`, `execute_user`, `last_exec_time`, `last_exec_result`, `pos`)
|
||||||
|
VALUES ('wx_tpfc_1', 5000, 'wx_test_plan_id_4', 'wx_fc_1', 1714980158000, 'admin', NULL, NULL, NULL, 1);
|
||||||
|
|
Loading…
Reference in New Issue