feat(测试计划): 新增测试规划脑图获取接口
This commit is contained in:
parent
4b3a474f1c
commit
3fe1bc68dd
|
@ -118,4 +118,12 @@ test_plan_report_name_length_range=报告名称长度过长
|
|||
test_plan_schedule=测试计划-定時任務
|
||||
test_plan_default_functional_collection_name=基本功能点
|
||||
test_plan_default_api_collection_name=单接口验证
|
||||
test_plan_default_scenario_collection_name=业务流程验证
|
||||
test_plan_default_scenario_collection_name=业务流程验证
|
||||
test_plan.mind.test_plan=测试规划
|
||||
test_plan.mind.serial=串
|
||||
test_plan.mind.parallel=并
|
||||
test_plan.mind.strip=条
|
||||
test_plan.mind.case_count=用例数
|
||||
test_plan.mind.environment=环境
|
||||
test_plan.mind.test_resource_pool=资源池
|
||||
|
||||
|
|
|
@ -121,4 +121,11 @@ test_plan_report_name_length_range=The report name is too long
|
|||
test_plan_schedule=Test plan schedule
|
||||
test_plan_default_functional_collection_name=Basic function point
|
||||
test_plan_default_api_collection_name=Single interface verification
|
||||
test_plan_default_scenario_collection_name=Business process verification
|
||||
test_plan_default_scenario_collection_name=Business process verification
|
||||
test_plan.mind.test_plan=Test plan
|
||||
test_plan.mind.serial=Serial
|
||||
test_plan.mind.parallel=Parallel
|
||||
test_plan.mind.strip=Strip
|
||||
test_plan.mind.case_count=Count
|
||||
test_plan.mind.environment=Environment
|
||||
test_plan.mind.test_resource_pool=Resource pool
|
|
@ -121,4 +121,11 @@ test_plan_report_name_length_range=报告名称长度过长
|
|||
test_plan_schedule=测试计划-定時任務
|
||||
test_plan_default_functional_collection_name=基本功能点
|
||||
test_plan_default_api_collection_name=单接口验证
|
||||
test_plan_default_scenario_collection_name=业务流程验证
|
||||
test_plan_default_scenario_collection_name=业务流程验证
|
||||
test_plan.mind.test_plan=测试规划
|
||||
test_plan.mind.serial=串
|
||||
test_plan.mind.parallel=并
|
||||
test_plan.mind.strip=条
|
||||
test_plan.mind.case_count=用例数
|
||||
test_plan.mind.environment=环境
|
||||
test_plan.mind.test_resource_pool=资源池
|
|
@ -120,4 +120,11 @@ test_plan_report_name_length_range=报告名称长度过长
|
|||
test_plan_schedule=測試計劃-定時任務
|
||||
test_plan_default_functional_collection_name=基本功能點
|
||||
test_plan_default_api_collection_name=單接口驗證
|
||||
test_plan_default_scenario_collection_name=業務流程驗證
|
||||
test_plan_default_scenario_collection_name=業務流程驗證
|
||||
test_plan.mind.test_plan=測試規劃
|
||||
test_plan.mind.serial=串
|
||||
test_plan.mind.parallel=並
|
||||
test_plan.mind.strip=條
|
||||
test_plan.mind.case_count=用例數
|
||||
test_plan.mind.environment=環境
|
||||
test_plan.mind.test_resource_pool=資源池
|
|
@ -294,9 +294,10 @@ public class FunctionalCaseMinderService {
|
|||
Map<String, String> newModuleMap = new HashMap<>();
|
||||
|
||||
//处理模块
|
||||
dealModule(request, userId, moduleMapper, newModuleMap);
|
||||
List<String> moduleNodeIds = dealModule(request, userId, moduleMapper, newModuleMap);
|
||||
|
||||
//处理用例
|
||||
List<String> caseNodeIds = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(request.getUpdateCaseList())) {
|
||||
Map<String, List<FunctionalCaseChangeRequest>> resourceMap = request.getUpdateCaseList().stream().collect(Collectors.groupingBy(FunctionalCaseChangeRequest::getType));
|
||||
//处理新增
|
||||
|
@ -310,6 +311,7 @@ public class FunctionalCaseMinderService {
|
|||
FunctionalCase functionalCase = addCase(request, userId, functionalCaseChangeRequest, caseMapper, newModuleMap);
|
||||
String caseId = functionalCase.getId();
|
||||
//附属表
|
||||
caseNodeIds.add(caseId);
|
||||
FunctionalCaseBlob functionalCaseBlob = addCaseBlob(functionalCaseChangeRequest, caseId, caseBlobMapper);
|
||||
//保存自定义字段
|
||||
List<FunctionalCaseCustomField> functionalCaseCustomFields = addCustomFields(functionalCaseChangeRequest, caseId, caseCustomFieldMapper, defaultValueMap);
|
||||
|
@ -366,16 +368,14 @@ public class FunctionalCaseMinderService {
|
|||
}
|
||||
//批量排序
|
||||
batchSort(updatePosList, caseMapper);
|
||||
|
||||
}
|
||||
|
||||
//处理空白节点
|
||||
dealAdditionalNode(request, userId, additionalNodeMapper, newModuleMap);
|
||||
|
||||
//TODO:删除转换的空白节点
|
||||
|
||||
|
||||
|
||||
moduleNodeIds.addAll(caseNodeIds);
|
||||
if (CollectionUtils.isNotEmpty(moduleNodeIds)) {
|
||||
dealMindAdditionalMode(moduleNodeIds);
|
||||
}
|
||||
|
||||
sqlSession.flushStatements();
|
||||
SqlSessionUtils.closeSqlSession(sqlSession, sqlSessionFactory);
|
||||
|
@ -553,7 +553,8 @@ public class FunctionalCaseMinderService {
|
|||
|
||||
}
|
||||
|
||||
private void dealModule(FunctionalCaseMinderEditRequest request, String userId, FunctionalCaseModuleMapper moduleMapper, Map<String, String> newModuleMap) {
|
||||
private List<String> dealModule(FunctionalCaseMinderEditRequest request, String userId, FunctionalCaseModuleMapper moduleMapper, Map<String, String> newModuleMap) {
|
||||
List<String> nodeIds = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(request.getUpdateModuleList())) {
|
||||
List<FunctionalCaseModule> updatePosList = new ArrayList<>();
|
||||
//处理新增
|
||||
|
@ -573,6 +574,7 @@ public class FunctionalCaseMinderService {
|
|||
if (StringUtils.isNotBlank(newModuleMap.get(module.getParentId()))) {
|
||||
module.setParentId(newModuleMap.get(module.getParentId()));
|
||||
}
|
||||
nodeIds.add(module.getId());
|
||||
moduleMapper.insert(module);
|
||||
}
|
||||
parentModuleMap.forEach((k, v) -> {
|
||||
|
@ -584,7 +586,7 @@ public class FunctionalCaseMinderService {
|
|||
List<FunctionalCaseModuleEditRequest> updateList = resourceMap.get(OperationLogType.UPDATE.toString());
|
||||
if (CollectionUtils.isNotEmpty(updateList)) {
|
||||
List<FunctionalCaseModule> modules = new ArrayList<>();
|
||||
Map<String, List<FunctionalCaseModule>> parentModuleMap = getParentModuleMap(addList);
|
||||
Map<String, List<FunctionalCaseModule>> parentModuleMap = getParentModuleMap(updateList);
|
||||
for (FunctionalCaseModuleEditRequest functionalCaseModuleEditRequest : updateList) {
|
||||
checkModules(functionalCaseModuleEditRequest, parentModuleMap);
|
||||
FunctionalCaseModule updateModule = updateModule(userId, functionalCaseModuleEditRequest, moduleMapper);
|
||||
|
@ -604,6 +606,7 @@ public class FunctionalCaseMinderService {
|
|||
//批量排序
|
||||
batchSortModule(updatePosList, moduleMapper);
|
||||
}
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
private static void batchSortModule(List<FunctionalCaseModule> updatePosList, FunctionalCaseModuleMapper moduleMapper) {
|
||||
|
@ -1038,13 +1041,17 @@ public class FunctionalCaseMinderService {
|
|||
List<MinderOptionDTO> additionalOptionDTOS = resourceMap.get(ModuleConstants.ROOT_NODE_PARENT_ID);
|
||||
if (CollectionUtils.isNotEmpty(additionalOptionDTOS)) {
|
||||
List<String> mindAdditionalNodeIds = caseModuleOptionDTOS.stream().map(MinderOptionDTO::getId).toList();
|
||||
MindAdditionalNodeExample mindAdditionalNodeExample = new MindAdditionalNodeExample();
|
||||
mindAdditionalNodeExample.createCriteria().andIdIn(mindAdditionalNodeIds);
|
||||
mindAdditionalNodeMapper.deleteByExample(mindAdditionalNodeExample);
|
||||
dealMindAdditionalMode(mindAdditionalNodeIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void dealMindAdditionalMode(List<String> mindAdditionalNodeIds) {
|
||||
MindAdditionalNodeExample mindAdditionalNodeExample = new MindAdditionalNodeExample();
|
||||
mindAdditionalNodeExample.createCriteria().andIdIn(mindAdditionalNodeIds);
|
||||
mindAdditionalNodeMapper.deleteByExample(mindAdditionalNodeExample);
|
||||
}
|
||||
|
||||
|
||||
public List<FunctionalMinderTreeDTO> getReviewMindFunctionalCase(FunctionalCaseReviewMindRequest request, boolean deleted, String userId, String viewStatusUserId) {
|
||||
List<FunctionalMinderTreeDTO> list = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package io.metersphere.plan.controller;
|
||||
|
||||
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO;
|
||||
import io.metersphere.plan.service.TestPlanCollectionMinderService;
|
||||
import io.metersphere.sdk.constants.PermissionConstants;
|
||||
import io.metersphere.system.security.CheckOwner;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "测试规划脑图")
|
||||
@RestController
|
||||
@RequestMapping("/test-plan/mind")
|
||||
public class TestPlanCollectionMinderController {
|
||||
|
||||
@Resource
|
||||
private TestPlanCollectionMinderService testPlanCollectionMinderService;
|
||||
|
||||
@GetMapping("/data/{planId}")
|
||||
@Operation(summary = "测试规划脑图列表")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ_UPDATE)
|
||||
@CheckOwner(resourceId = "#planId", resourceType = "test_plan")
|
||||
public List<TestPlanCollectionMinderTreeDTO> getMindTestPlanCase(@PathVariable String planId) {
|
||||
return testPlanCollectionMinderService.getMindTestPlanCase(planId);
|
||||
}
|
||||
|
||||
}
|
|
@ -34,4 +34,34 @@ public class TestPlanCollectionMinderTreeNodeDTO {
|
|||
@Schema(description = "节点状态")
|
||||
private String expandState = "expand";
|
||||
|
||||
@Schema(description = "测试集类型(功能/接口/场景)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String type;
|
||||
|
||||
@Schema(description = "是否继承", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean extended;
|
||||
|
||||
@Schema(description = "是否使用环境组", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean grouped;
|
||||
|
||||
@Schema(description = "环境ID/环境组ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String environmentId;
|
||||
|
||||
@Schema(description = "测试资源池ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String testResourcePoolId;
|
||||
|
||||
@Schema(description = "是否失败重试", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean retryOnFail;
|
||||
|
||||
@Schema(description = "失败重试类型(步骤/场景)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String retryType;
|
||||
|
||||
@Schema(description = "失败重试次数", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer retryTimes;
|
||||
|
||||
@Schema(description = "失败重试间隔(单位: ms)", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer retryInterval;
|
||||
|
||||
@Schema(description = "是否失败停止", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean stopOnFail;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package io.metersphere.plan.mapper;
|
||||
|
||||
import io.metersphere.plan.dto.TestPlanCollectionConfigDTO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ExtTestPlanCollectionMapper {
|
||||
|
||||
List<TestPlanCollectionConfigDTO> getList(@Param("planId") String planId);
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.metersphere.plan.mapper.ExtTestPlanCollectionMapper">
|
||||
|
||||
<select id="getList" resultType="io.metersphere.plan.dto.TestPlanCollectionConfigDTO">
|
||||
SELECT
|
||||
tpc.id, tpc.test_plan_id, tpc.parent_id,
|
||||
tpc.`name`, tpc.`type`, tpc.execute_method,
|
||||
tpc.extended, tpc.grouped, tpc.environment_id,
|
||||
tpc.test_resource_pool_id, tpc.retry_on_fail, tpc.retry_type,
|
||||
tpc.retry_times, tpc.retry_interval, tpc.stop_on_fail,
|
||||
tpc.create_user, tpc.create_time, tpc.pos,
|
||||
trp.name as poolName,
|
||||
IF(env.name is not null, env.name, envg.name) as envName
|
||||
FROM
|
||||
test_plan_collection tpc
|
||||
LEFT JOIN test_resource_pool trp ON tpc.test_resource_pool_id = trp.id
|
||||
LEFT JOIN environment env ON tpc.environment_id = env.id
|
||||
LEFT JOIN environment_group envg ON tpc.test_resource_pool_id = envg.id
|
||||
WHERE tpc.test_plan_id = #{planId}
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -1,101 +1,220 @@
|
|||
package io.metersphere.plan.service;
|
||||
|
||||
import io.metersphere.plan.domain.TestPlanCollection;
|
||||
import io.metersphere.plan.domain.TestPlanCollectionExample;
|
||||
import io.metersphere.plan.domain.*;
|
||||
import io.metersphere.plan.dto.TestPlanCollectionConfigDTO;
|
||||
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO;
|
||||
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeNodeDTO;
|
||||
import io.metersphere.plan.mapper.TestPlanCollectionMapper;
|
||||
import io.metersphere.plan.mapper.ExtTestPlanCollectionMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanApiCaseMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.mapper.TestPlanFunctionalCaseMapper;
|
||||
import io.metersphere.sdk.constants.ApiBatchRunMode;
|
||||
import io.metersphere.sdk.constants.CaseType;
|
||||
import io.metersphere.sdk.constants.ModuleConstants;
|
||||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class TestPlanCollectionMinderService {
|
||||
|
||||
@Resource
|
||||
private TestPlanCollectionMapper testPlanCollectionMapper;
|
||||
private ExtTestPlanCollectionMapper extTestPlanCollectionMapper;
|
||||
|
||||
@Resource
|
||||
private TestPlanFunctionalCaseMapper testPlanFunctionalCaseMapper;
|
||||
|
||||
@Resource
|
||||
private TestPlanApiCaseMapper testPlanApiCaseMapper;
|
||||
|
||||
@Resource
|
||||
private TestPlanApiScenarioMapper testPlanApiScenarioMapper;
|
||||
|
||||
/**
|
||||
* 测试计划-脑图用例列表查询
|
||||
*
|
||||
* @return FunctionalMinderTreeDTO
|
||||
*/
|
||||
public List<TestPlanCollectionMinderTreeDTO> getMindFunctionalCase(String planId) {
|
||||
public List<TestPlanCollectionMinderTreeDTO> getMindTestPlanCase(String planId) {
|
||||
List<TestPlanCollectionMinderTreeDTO> list = new ArrayList<>();
|
||||
TestPlanCollectionExample testPlanCollectionExample = new TestPlanCollectionExample();
|
||||
testPlanCollectionExample.createCriteria().andTestPlanIdEqualTo(planId);
|
||||
List<TestPlanCollection> testPlanCollections = testPlanCollectionMapper.selectByExample(testPlanCollectionExample);
|
||||
List<TestPlanCollectionConfigDTO> testPlanCollections = extTestPlanCollectionMapper.getList(planId);
|
||||
//构造根节点
|
||||
TestPlanCollectionMinderTreeNodeDTO testPlanCollectionMinderTreeNodeDTO = buildRoot();
|
||||
//
|
||||
TestPlanCollectionMinderTreeDTO testPlanCollectionMinderTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
testPlanCollectionMinderTreeDTO.setData(testPlanCollectionMinderTreeNodeDTO);
|
||||
//构造type节点
|
||||
List<TestPlanCollectionMinderTreeDTO> children = new ArrayList<>();
|
||||
List<TestPlanCollection> parentList = testPlanCollections.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)).sorted(Comparator.comparing(TestPlanCollection::getPos)).toList();
|
||||
List<TestPlanCollectionConfigDTO> parentList = testPlanCollections.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getParentId(), ModuleConstants.ROOT_NODE_PARENT_ID)).sorted(Comparator.comparing(TestPlanCollection::getPos)).toList();
|
||||
buildTypeChildren(parentList, testPlanCollections, children);
|
||||
testPlanCollectionMinderTreeDTO.setChildren(children);
|
||||
list.add(testPlanCollectionMinderTreeDTO);
|
||||
return list;
|
||||
}
|
||||
|
||||
private static void buildTypeChildren(List<TestPlanCollection> parentList, List<TestPlanCollection> testPlanCollections, List<TestPlanCollectionMinderTreeDTO> children) {
|
||||
private void buildTypeChildren(List<TestPlanCollectionConfigDTO> parentList, List<TestPlanCollectionConfigDTO> testPlanCollections, List<TestPlanCollectionMinderTreeDTO> children) {
|
||||
for (TestPlanCollection testPlanCollection : parentList) {
|
||||
TestPlanCollectionMinderTreeDTO treeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO typeTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
typeTreeNodeDTO.setId(testPlanCollection.getId());
|
||||
typeTreeNodeDTO.setText(testPlanCollection.getName());
|
||||
typeTreeNodeDTO.setPos(testPlanCollection.getPos());
|
||||
if (StringUtils.equalsIgnoreCase(testPlanCollection.getExecuteMethod(), ApiBatchRunMode.PARALLEL.toString())) {
|
||||
typeTreeNodeDTO.setPriority("并");
|
||||
} else {
|
||||
typeTreeNodeDTO.setPriority("串");
|
||||
}
|
||||
typeTreeNodeDTO.setExecuteMethod(testPlanCollection.getExecuteMethod());
|
||||
TestPlanCollectionMinderTreeDTO typeTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO typeTreeNodeDTO = buildTypeChildData(testPlanCollection);
|
||||
//构造子节点
|
||||
List<TestPlanCollectionMinderTreeDTO> collectionChildren = new ArrayList<>();
|
||||
List<TestPlanCollection> childrenList = testPlanCollections.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getParentId(), testPlanCollection.getId())).sorted(Comparator.comparing(TestPlanCollection::getPos)).toList();
|
||||
buildCollectionChildren(childrenList, collectionChildren);
|
||||
treeDTO.setData(typeTreeNodeDTO);
|
||||
treeDTO.setChildren(collectionChildren);
|
||||
children.add(treeDTO);
|
||||
List<TestPlanCollectionConfigDTO> childrenList = testPlanCollections.stream().filter(t -> StringUtils.equalsIgnoreCase(t.getParentId(), testPlanCollection.getId())).sorted(Comparator.comparing(TestPlanCollection::getPos)).toList();
|
||||
Map<String, List<TestPlanCollectionConfigDTO>> typeChildren = childrenList.stream().collect(Collectors.groupingBy(TestPlanCollectionConfigDTO::getType));
|
||||
Map<String, List<TestPlanFunctionalCase>> testPlanFunctionalCaseMap = getTestPlanFunctionalCases(typeChildren);
|
||||
Map<String, List<TestPlanApiCase>> testPlanApiCaseMap = getTestPlanApiCases(typeChildren);
|
||||
Map<String, List<TestPlanApiScenario>> testPlanApiScenarioMap = getTestPlanApiScenarios(typeChildren);
|
||||
buildCollectionChildren(childrenList, collectionChildren, testPlanFunctionalCaseMap, testPlanApiCaseMap, testPlanApiScenarioMap);
|
||||
typeTreeDTO.setData(typeTreeNodeDTO);
|
||||
typeTreeDTO.setChildren(collectionChildren);
|
||||
children.add(typeTreeDTO);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildCollectionChildren(List<TestPlanCollection> childrenList, List<TestPlanCollectionMinderTreeDTO> collectionChildren) {
|
||||
for (TestPlanCollection planCollection : childrenList) {
|
||||
@NotNull
|
||||
private static TestPlanCollectionMinderTreeNodeDTO buildTypeChildData(TestPlanCollection testPlanCollection) {
|
||||
TestPlanCollectionMinderTreeNodeDTO typeTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
BeanUtils.copyBean(typeTreeNodeDTO, testPlanCollection);
|
||||
typeTreeNodeDTO.setText(testPlanCollection.getName());
|
||||
if (StringUtils.equalsIgnoreCase(testPlanCollection.getExecuteMethod(), ApiBatchRunMode.PARALLEL.toString())) {
|
||||
typeTreeNodeDTO.setPriority(Translator.get("test_plan.mind.serial"));
|
||||
} else {
|
||||
typeTreeNodeDTO.setPriority(Translator.get("test_plan.mind.parallel"));
|
||||
}
|
||||
return typeTreeNodeDTO;
|
||||
}
|
||||
|
||||
private Map<String, List<TestPlanApiScenario>> getTestPlanApiScenarios(Map<String, List<TestPlanCollectionConfigDTO>> typeChildren) {
|
||||
List<TestPlanCollectionConfigDTO> testPlanCollectionConfigDTOS = typeChildren.get(CaseType.SCENARIO_CASE.getKey());
|
||||
if (CollectionUtils.isEmpty(testPlanCollectionConfigDTOS)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
List<String> scenarioCollectIds = testPlanCollectionConfigDTOS.stream().map(TestPlanCollectionConfigDTO::getId).toList();
|
||||
TestPlanApiScenarioExample testPlanApiScenarioExample = new TestPlanApiScenarioExample();
|
||||
testPlanApiScenarioExample.createCriteria().andTestPlanCollectionIdIn(scenarioCollectIds);
|
||||
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMapper.selectByExample(testPlanApiScenarioExample);
|
||||
return testPlanApiScenarios.stream().collect(Collectors.groupingBy(TestPlanApiScenario::getTestPlanCollectionId));
|
||||
}
|
||||
|
||||
private Map<String, List<TestPlanApiCase>> getTestPlanApiCases(Map<String, List<TestPlanCollectionConfigDTO>> typeChildren) {
|
||||
List<TestPlanCollectionConfigDTO> testPlanCollectionConfigDTOS = typeChildren.get(CaseType.API_CASE.getKey());
|
||||
if (CollectionUtils.isEmpty(testPlanCollectionConfigDTOS)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
List<String> apiCollectIds = testPlanCollectionConfigDTOS.stream().map(TestPlanCollectionConfigDTO::getId).toList();
|
||||
TestPlanApiCaseExample testPlanApiCaseExample = new TestPlanApiCaseExample();
|
||||
testPlanApiCaseExample.createCriteria().andTestPlanCollectionIdIn(apiCollectIds);
|
||||
List<TestPlanApiCase> testPlanApiCases = testPlanApiCaseMapper.selectByExample(testPlanApiCaseExample);
|
||||
return testPlanApiCases.stream().collect(Collectors.groupingBy(TestPlanApiCase::getTestPlanCollectionId));
|
||||
|
||||
}
|
||||
|
||||
private Map<String, List<TestPlanFunctionalCase>> getTestPlanFunctionalCases(Map<String, List<TestPlanCollectionConfigDTO>> typeChildren) {
|
||||
List<TestPlanCollectionConfigDTO> testPlanCollectionConfigDTOS = typeChildren.get(CaseType.FUNCTIONAL_CASE.getKey());
|
||||
if (CollectionUtils.isEmpty(testPlanCollectionConfigDTOS)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
List<String> functionalCollectIds = testPlanCollectionConfigDTOS.stream().map(TestPlanCollectionConfigDTO::getId).toList();
|
||||
TestPlanFunctionalCaseExample testPlanFunctionalCaseExample = new TestPlanFunctionalCaseExample();
|
||||
testPlanFunctionalCaseExample.createCriteria().andTestPlanCollectionIdIn(functionalCollectIds);
|
||||
List<TestPlanFunctionalCase> testPlanFunctionalCases = testPlanFunctionalCaseMapper.selectByExample(testPlanFunctionalCaseExample);
|
||||
return testPlanFunctionalCases.stream().collect(Collectors.groupingBy(TestPlanFunctionalCase::getTestPlanCollectionId));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void buildCollectionChildren(List<TestPlanCollectionConfigDTO> childrenList, List<TestPlanCollectionMinderTreeDTO> collectionChildren, Map<String, List<TestPlanFunctionalCase>> testPlanFunctionalCaseMap, Map<String, List<TestPlanApiCase>> testPlanApiCaseMap, Map<String, List<TestPlanApiScenario>> testPlanApiScenarioMap) {
|
||||
for (TestPlanCollectionConfigDTO planCollection : childrenList) {
|
||||
TestPlanCollectionMinderTreeDTO collectionTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO collectionTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
collectionTreeNodeDTO.setId(planCollection.getId());
|
||||
collectionTreeNodeDTO.setText(planCollection.getName());
|
||||
collectionTreeNodeDTO.setPos(planCollection.getPos());
|
||||
if (StringUtils.equalsIgnoreCase(planCollection.getExecuteMethod(), ApiBatchRunMode.PARALLEL.toString())) {
|
||||
collectionTreeNodeDTO.setPriority("并");
|
||||
} else {
|
||||
collectionTreeNodeDTO.setPriority("串");
|
||||
}
|
||||
collectionTreeNodeDTO.setExecuteMethod(planCollection.getExecuteMethod());
|
||||
TestPlanCollectionMinderTreeNodeDTO collectionTreeNodeDTO = buildTypeChildData(planCollection);
|
||||
collectionTreeNodeDTO.setResource(new ArrayList<>());
|
||||
//TODO:构造子集
|
||||
|
||||
|
||||
List<TestPlanCollectionMinderTreeDTO> endList = getEndList(testPlanFunctionalCaseMap, testPlanApiCaseMap, testPlanApiScenarioMap, planCollection);
|
||||
collectionTreeDTO.setData(collectionTreeNodeDTO);
|
||||
collectionTreeDTO.setChildren(new ArrayList<>());
|
||||
collectionTreeDTO.setChildren(endList);
|
||||
collectionChildren.add(collectionTreeDTO);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<TestPlanCollectionMinderTreeDTO> getEndList(Map<String, List<TestPlanFunctionalCase>> testPlanFunctionalCaseMap, Map<String, List<TestPlanApiCase>> testPlanApiCaseMap, Map<String, List<TestPlanApiScenario>> testPlanApiScenarioMap, TestPlanCollectionConfigDTO planCollection) {
|
||||
List<TestPlanCollectionMinderTreeDTO> endList = new ArrayList<>();
|
||||
if (StringUtils.equalsIgnoreCase(planCollection.getType(), CaseType.FUNCTIONAL_CASE.getKey())) {
|
||||
buildFunctionalChild(testPlanFunctionalCaseMap, planCollection, endList);
|
||||
} else if (StringUtils.equalsIgnoreCase(planCollection.getType(), CaseType.API_CASE.getKey())) {
|
||||
buildApiCaseChild(testPlanApiCaseMap, planCollection, endList);
|
||||
} else {
|
||||
buildScenarioChild(testPlanApiScenarioMap, planCollection, endList);
|
||||
}
|
||||
return endList;
|
||||
}
|
||||
|
||||
private static void buildScenarioChild(Map<String, List<TestPlanApiScenario>> testPlanApiScenarioMap, TestPlanCollectionConfigDTO planCollection, List<TestPlanCollectionMinderTreeDTO> endList) {
|
||||
TestPlanCollectionMinderTreeDTO countTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO countTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
List<TestPlanApiScenario> testPlanApiScenarios = testPlanApiScenarioMap.get(planCollection.getId());
|
||||
int count = 0;
|
||||
if (CollectionUtils.isNotEmpty(testPlanApiScenarios)) {
|
||||
count = testPlanApiScenarios.size();
|
||||
}
|
||||
buildChild(countTreeNodeDTO, count + Translator.get("test_plan.mind.strip"), "test_plan.mind.case_count", countTreeDTO, endList);
|
||||
TestPlanCollectionMinderTreeDTO envTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO envTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
buildChild(envTreeNodeDTO, planCollection.getEnvName(), "test_plan.mind.environment", envTreeDTO, endList);
|
||||
TestPlanCollectionMinderTreeDTO poolTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO poolTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
buildChild(poolTreeNodeDTO, planCollection.getPoolName(), "test_plan.mind.test_resource_pool", poolTreeDTO, endList);
|
||||
}
|
||||
|
||||
private static void buildChild(TestPlanCollectionMinderTreeNodeDTO treeNodeDTO, String text, String key, TestPlanCollectionMinderTreeDTO treeDTO, List<TestPlanCollectionMinderTreeDTO> endList) {
|
||||
treeNodeDTO.setText(text);
|
||||
treeNodeDTO.setResource(List.of(Translator.get(key)));
|
||||
treeDTO.setData(treeNodeDTO);
|
||||
treeDTO.setChildren(new ArrayList<>());
|
||||
if (StringUtils.isNotBlank(text)) {
|
||||
endList.add(treeDTO);
|
||||
}
|
||||
}
|
||||
|
||||
private static void buildApiCaseChild(Map<String, List<TestPlanApiCase>> testPlanApiCaseMap, TestPlanCollectionConfigDTO planCollection, List<TestPlanCollectionMinderTreeDTO> endList) {
|
||||
TestPlanCollectionMinderTreeDTO countTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO countTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
List<TestPlanApiCase> testPlanApiCases = testPlanApiCaseMap.get(planCollection.getId());
|
||||
int count = 0;
|
||||
if (CollectionUtils.isNotEmpty(testPlanApiCases)) {
|
||||
count = testPlanApiCases.size();
|
||||
}
|
||||
buildChild(countTreeNodeDTO, count + Translator.get("test_plan.mind.strip"), "test_plan.mind.case_count", countTreeDTO, endList);
|
||||
TestPlanCollectionMinderTreeDTO envTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO envTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
buildChild(envTreeNodeDTO, planCollection.getEnvName(), "test_plan.mind.environment", envTreeDTO, endList);
|
||||
TestPlanCollectionMinderTreeDTO poolTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO poolTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
buildChild(poolTreeNodeDTO, planCollection.getPoolName(), "test_plan.mind.test_resource_pool", poolTreeDTO, endList);
|
||||
}
|
||||
|
||||
private static void buildFunctionalChild(Map<String, List<TestPlanFunctionalCase>> testPlanFunctionalCaseMap, TestPlanCollectionConfigDTO planCollection, List<TestPlanCollectionMinderTreeDTO> endList) {
|
||||
List<TestPlanFunctionalCase> testPlanFunctionalCases = testPlanFunctionalCaseMap.get(planCollection.getId());
|
||||
int count = 0;
|
||||
if (CollectionUtils.isNotEmpty(testPlanFunctionalCases)) {
|
||||
count = testPlanFunctionalCases.size();
|
||||
}
|
||||
TestPlanCollectionMinderTreeDTO countTreeDTO = new TestPlanCollectionMinderTreeDTO();
|
||||
TestPlanCollectionMinderTreeNodeDTO countTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
buildChild(countTreeNodeDTO, count + Translator.get("test_plan.mind.strip"), "test_plan.mind.case_count", countTreeDTO, endList);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static TestPlanCollectionMinderTreeNodeDTO buildRoot() {
|
||||
TestPlanCollectionMinderTreeNodeDTO testPlanCollectionMinderTreeNodeDTO = new TestPlanCollectionMinderTreeNodeDTO();
|
||||
testPlanCollectionMinderTreeNodeDTO.setId(ModuleConstants.DEFAULT_NODE_ID);
|
||||
testPlanCollectionMinderTreeNodeDTO.setText("测试规划");
|
||||
testPlanCollectionMinderTreeNodeDTO.setText(Translator.get("test_plan.mind.test_plan"));
|
||||
testPlanCollectionMinderTreeNodeDTO.setResource(new ArrayList<>());
|
||||
return testPlanCollectionMinderTreeNodeDTO;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package io.metersphere.plan.controller;
|
||||
|
||||
import io.metersphere.plan.dto.TestPlanCollectionMinderTreeDTO;
|
||||
import io.metersphere.sdk.util.JSON;
|
||||
import io.metersphere.system.base.BaseTest;
|
||||
import io.metersphere.system.controller.handler.ResultHolder;
|
||||
import org.junit.jupiter.api.*;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
@AutoConfigureMockMvc
|
||||
public class TestPlanCollectionMinderControllerTests extends BaseTest {
|
||||
|
||||
private static final String PLAN_MIND = "/test-plan/mind/data/";
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
@Sql(scripts = {"/dml/init_test_plan_mind.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
void tesPagePlanReportSuccess() throws Exception {
|
||||
|
||||
MvcResult mvcResult = this.requestGetWithOkAndReturn(PLAN_MIND+"gyq_plan_1");
|
||||
// 获取返回值
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
// 返回请求正常
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
List<TestPlanCollectionMinderTreeDTO> testPlanCollectionMinderTreeDTOS = JSON.parseArray(JSON.toJSONString(resultHolder.getData()), TestPlanCollectionMinderTreeDTO.class);
|
||||
// 返回值不为空
|
||||
Assertions.assertNotNull(testPlanCollectionMinderTreeDTOS);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
|
||||
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
|
||||
('gyq_plan_1', 5000, 'gyq_plan_project', 'NONE', '1', 'qwe', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'admin', 1714980158000, 'admin', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11'),
|
||||
('gyq_plan_2', 10000, 'gyq_plan_project', 'NONE', '1', 'eeew', 'PREPARED', 'TEST_PLAN', NULL, 1714980158000, 'admin', 1714980158000, 'admin', 1714980158000, 1714980158000, 1714980158000, 1714980158000, '11');
|
||||
|
||||
|
||||
INSERT INTO project (id, num, organization_id, name, description, create_user, update_user, create_time, update_time)
|
||||
VALUES ('gyq_plan_project', null, 'organization-associate-case-test', '用例评论项目', '系统默认创建的项目',
|
||||
'admin', 'admin', UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000);
|
||||
|
||||
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 ('gyq_wxxx_1', 'gyq_plan_1', 'wxxx_api_case_1', 'gyq_123', NULL, NULL, 'admin', 1716370415311, 'admin', 2, 'gyq_wxxx_4', 1716370415311);
|
||||
|
||||
INSERT INTO `test_plan_functional_case`(id, test_plan_id, functional_case_id, create_time, create_user, execute_user, last_exec_time, last_exec_result, pos, test_plan_collection_id)
|
||||
VALUES('gyq_functional_case_1', 'gyq_plan_1', 'functional_case_id', 1716797474979, 'admin', 'admin', 1716866691313, 'SUCCESS', 4096, 'gyq_wxxx_5');
|
||||
|
||||
|
||||
INSERT INTO `test_plan_api_scenario`(id, test_plan_id, api_scenario_id, environment_id, execute_user, last_exec_result, last_exec_report_id, create_time, create_user, pos, test_plan_collection_id, grouped, last_exec_time)
|
||||
VALUES ('gyq_scenario_case_1', 'gyq_plan_1', 'api_scenario_id', 'gyq_123','admin', 'SUCCESS', 'last_exec_report_id', 1716866691313,'admin', 4096, 'gyq_wxxx_6', b'0', 1716866691313);
|
||||
|
||||
|
||||
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
|
||||
('gyq_wxxx_1', 'gyq_plan_1', '接口用例', 'API', 'NONE', 'gyq_123_pool', 1, 'admin', 1716370415311, 'NONE'),
|
||||
('gyq_wxxx_2', 'gyq_plan_1', '功能用例', 'FUNCTIONAL', 'gyq_123', 'gyq_123_pool', 2, 'admin', 1716370415311, 'NONE'),
|
||||
('gyq_wxxx_3', 'gyq_plan_1', '场景用例', 'SCENARIO', 'NONE', 'NONE', 3, 'admin', 1716370415311, 'NONE'),
|
||||
('gyq_wxxx_4', 'gyq_plan_1', '接口测试集', 'API', 'NONE', 'gyq_123_pool', 1, 'admin', 1716370415311, 'gyq_wxxx_1'),
|
||||
('gyq_wxxx_5', 'gyq_plan_1', '功能测试集', 'FUNCTIONAL', 'gyq_123', 'gyq_123_pool', 2, 'admin', 1716370415311, 'gyq_wxxx_2'),
|
||||
('gyq_wxxx_6', 'gyq_plan_1', '场景测试集', 'SCENARIO', 'NONE', 'gyq_123_pool', 3, 'admin', 1716370415311, 'gyq_wxxx_3');
|
||||
|
||||
|
||||
INSERT INTO `environment`(`id`, `name`, `project_id`, `create_user`, `update_user`, `create_time`, `update_time`, `mock`, `description`, `pos`)
|
||||
VALUES ('gyq_123', 'Mock环境', 'wxx_1234', 'admin', 'admin', 1716175907000, 1716175907000, b'1', NULL, 64);
|
||||
|
||||
INSERT INTO test_resource_pool (id, name, type, description, enable, create_time, update_time, create_user, all_org, deleted)
|
||||
VALUES ('gyq_123_pool', '默认资源池', 'Node', '系统初始化资源池', true, UNIX_TIMESTAMP() * 1000, UNIX_TIMESTAMP() * 1000, 'admin', true, false);
|
||||
|
||||
|
Loading…
Reference in New Issue