feat(测试计划): 功能用例新增测试集视图

This commit is contained in:
WangXu10 2024-06-12 17:45:29 +08:00 committed by 刘瑞斌
parent 5d97da2a78
commit b16dad62c2
10 changed files with 132 additions and 18 deletions

View File

@ -71,7 +71,7 @@ public class TestPlanApiScenarioController {
@Operation(summary = "测试计划-已关联场景用例列表模块树")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
public List<BaseTreeNode> getTree(@Validated @RequestBody TestPlanApiScenarioTreeRequest request) {
public List<BaseTreeNode> getTree(@Validated @RequestBody TestPlanTreeRequest request) {
return testPlanApiScenarioService.getTree(request);
}

View File

@ -65,19 +65,19 @@ public class TestPlanFunctionalCaseController {
return PageUtils.setPageInfo(page, testPlanFunctionalCaseService.getFunctionalCasePage(request, false));
}
@GetMapping("/tree/{testPlanId}")
@PostMapping("/tree")
@Operation(summary = "测试计划-已关联功能用例列表模块树")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#testPlanId", resourceType = "test_plan")
public List<BaseTreeNode> getTree(@PathVariable String testPlanId) {
return testPlanFunctionalCaseService.getTree(testPlanId);
public List<BaseTreeNode> getTree(@Validated @RequestBody TestPlanTreeRequest request) {
return testPlanFunctionalCaseService.getTree(request);
}
@PostMapping("/module/count")
@Operation(summary = "测试计划-已关联功能用例模块数量")
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
public Map<String, Long> moduleCount(@Validated @RequestBody TestPlanCaseRequest request) {
public Map<String, Long> moduleCount(@Validated @RequestBody TestPlanCaseModuleRequest request) {
return testPlanFunctionalCaseService.moduleCount(request);
}

View File

@ -0,0 +1,17 @@
package io.metersphere.plan.dto.request;
import io.metersphere.plan.constants.TreeTypeEnums;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
* @author wx
*/
@Data
public class TestPlanCaseModuleRequest extends TestPlanCaseRequest{
@Schema(description = "类型:模块/计划集", allowableValues = {"MODULE","COLLECTION"},requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "{test_plan.type.not_blank}")
private String treeType = TreeTypeEnums.COLLECTION;
}

View File

@ -12,7 +12,7 @@ import java.io.Serializable;
* @author wx
*/
@Data
public class TestPlanApiScenarioTreeRequest implements Serializable {
public class TestPlanTreeRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;

View File

@ -10,6 +10,7 @@ import io.metersphere.plan.dto.request.BasePlanCaseBatchRequest;
import io.metersphere.plan.dto.request.TestPlanCaseRequest;
import io.metersphere.plan.dto.response.TestPlanCasePageResponse;
import io.metersphere.project.dto.DropNode;
import io.metersphere.project.dto.ModuleCountDTO;
import io.metersphere.project.dto.NodeSortQueryParam;
import org.apache.ibatis.annotations.Param;
@ -60,4 +61,6 @@ public interface ExtTestPlanFunctionalCaseMapper {
List<TestPlanCaseRunResultCount> selectCaseExecResultCount(String testPlanId);
Long getMaxPosByCollectionId(String collectionId);
List<ModuleCountDTO> collectionCountByRequest(@Param("testPlanId") String testPlanId);
}

View File

@ -538,4 +538,17 @@
WHERE test_plan_collection_id = #{0}
</select>
<select id="collectionCountByRequest" parameterType="java.lang.String" resultType="io.metersphere.project.dto.ModuleCountDTO">
SELECT
test_plan_functional_case.test_plan_collection_id AS moduleId,
count( test_plan_functional_case.id ) AS dataCount
FROM
functional_case
INNER JOIN test_plan_functional_case ON functional_case.id = test_plan_functional_case.functional_case_id
WHERE
functional_case.deleted = FALSE
AND test_plan_functional_case.test_plan_id = #{testPlanId}
GROUP BY
test_plan_functional_case.test_plan_collection_id
</select>
</mapper>

View File

@ -423,7 +423,7 @@ public class TestPlanApiScenarioService extends TestPlanResourceService implemen
return apiScenarioModuleService.buildTreeAndCountResource(nodeByNodeIds, moduleCountDTOList, true, Translator.get("functional_case.module.default.name"));
}
public List<BaseTreeNode> getTree(TestPlanApiScenarioTreeRequest request) {
public List<BaseTreeNode> getTree(TestPlanTreeRequest request) {
switch (request.getTreeType()) {
case TreeTypeEnums.MODULE:
return getModuleTree(request.getTestPlanId());

View File

@ -18,6 +18,7 @@ import io.metersphere.functional.service.FunctionalCaseAttachmentService;
import io.metersphere.functional.service.FunctionalCaseModuleService;
import io.metersphere.functional.service.FunctionalCaseService;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.constants.TreeTypeEnums;
import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.ResourceLogInsertModule;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
@ -33,10 +34,7 @@ import io.metersphere.project.dto.MoveNodeSortDTO;
import io.metersphere.provider.BaseAssociateBugProvider;
import io.metersphere.request.AssociateBugPageRequest;
import io.metersphere.request.BugPageProviderRequest;
import io.metersphere.sdk.constants.CaseType;
import io.metersphere.sdk.constants.ExecStatus;
import io.metersphere.sdk.constants.HttpMethodConstants;
import io.metersphere.sdk.constants.TestPlanResourceConstants;
import io.metersphere.sdk.constants.*;
import io.metersphere.sdk.exception.MSException;
import io.metersphere.sdk.util.BeanUtils;
import io.metersphere.sdk.util.JSON;
@ -269,7 +267,42 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
.collect(Collectors.toSet());
}
public List<BaseTreeNode> getTree(String testPlanId) {
public List<BaseTreeNode> getTree(TestPlanTreeRequest request) {
switch (request.getTreeType()) {
case TreeTypeEnums.MODULE:
return getModuleTree(request.getTestPlanId());
case TreeTypeEnums.COLLECTION:
return getCollectionTree(request.getTestPlanId());
default:
return new ArrayList<>();
}
}
/**
* 已关联接口用例规划视图树
*
* @param testPlanId
* @return
*/
private List<BaseTreeNode> getCollectionTree(String testPlanId) {
List<BaseTreeNode> returnList = new ArrayList<>();
TestPlanCollectionExample collectionExample = new TestPlanCollectionExample();
collectionExample.createCriteria().andTypeEqualTo(CaseType.FUNCTIONAL_CASE.getKey()).andParentIdNotEqualTo(ModuleConstants.ROOT_NODE_PARENT_ID).andTestPlanIdEqualTo(testPlanId);
List<TestPlanCollection> testPlanCollections = testPlanCollectionMapper.selectByExample(collectionExample);
testPlanCollections.forEach(item -> {
BaseTreeNode baseTreeNode = new BaseTreeNode(item.getId(), item.getName(), CaseType.FUNCTIONAL_CASE.getKey());
returnList.add(baseTreeNode);
});
return returnList;
}
/**
* 模块树
*
* @param testPlanId
* @return
*/
private List<BaseTreeNode> getModuleTree(String testPlanId) {
List<BaseTreeNode> returnList = new ArrayList<>();
List<ProjectOptionDTO> rootIds = extTestPlanFunctionalCaseMapper.selectRootIdByTestPlanId(testPlanId);
Map<String, List<ProjectOptionDTO>> projectRootMap = rootIds.stream().collect(Collectors.groupingBy(ProjectOptionDTO::getName));
@ -299,7 +332,41 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
}
public Map<String, Long> moduleCount(TestPlanCaseRequest request) {
public Map<String, Long> moduleCount(TestPlanCaseModuleRequest request) {
switch (request.getTreeType()) {
case TreeTypeEnums.MODULE:
return getModuleCount(request);
case TreeTypeEnums.COLLECTION:
return getCollectionCount(request);
default:
return new HashMap<>();
}
}
/**
* 已关联接口用例规划视图统计
*
* @param request
* @return
*/
private Map<String, Long> getCollectionCount(TestPlanCaseModuleRequest request) {
Map<String, Long> projectModuleCountMap = new HashMap<>();
List<ModuleCountDTO> list = extTestPlanFunctionalCaseMapper.collectionCountByRequest(request.getTestPlanId());
list.forEach(item -> {
projectModuleCountMap.put(item.getModuleId(), (long) item.getDataCount());
});
long allCount = extTestPlanFunctionalCaseMapper.caseCount(request, false);
projectModuleCountMap.put(CASE_MODULE_COUNT_ALL, allCount);
return projectModuleCountMap;
}
/**
* 已关联接口用例模块树统计
*
* @param request
* @return
*/
private Map<String, Long> getModuleCount(TestPlanCaseModuleRequest request) {
//查出每个模块节点下的资源数量 不需要按照模块进行筛选
request.setModuleIds(null);
List<FunctionalCaseModuleCountDTO> projectModuleCountDTOList = extTestPlanFunctionalCaseMapper.countModuleIdByRequest(request, false);

View File

@ -317,7 +317,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
@Test
@Order(5)
public void testApiScenarioModuleTree() throws Exception {
TestPlanApiScenarioTreeRequest request = new TestPlanApiScenarioTreeRequest();
TestPlanTreeRequest request = new TestPlanTreeRequest();
request.setTestPlanId("wxxx_plan_1");
request.setTreeType("MODULE");
this.requestPostWithOkAndReturn(API_SCENARIO_TREE, request);

View File

@ -47,7 +47,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
public class TestPlanCaseControllerTests extends BaseTest {
public static final String FUNCTIONAL_CASE_LIST_URL = "/test-plan/functional/case/page";
public static final String FUNCTIONAL_CASE_TREE_URL = "/test-plan/functional/case/tree/";
public static final String FUNCTIONAL_CASE_TREE_URL = "/test-plan/functional/case/tree";
public static final String FUNCTIONAL_CASE_TREE_COUNT_URL = "/test-plan/functional/case/module/count";
public static final String FUNCTIONAL_CASE_DISASSOCIATE_URL = "/test-plan/functional/case/disassociate";
public static final String FUNCTIONAL_CASE_BATCH_DISASSOCIATE_URL = "/test-plan/functional/case/batch/disassociate";
@ -98,26 +98,40 @@ public class TestPlanCaseControllerTests extends BaseTest {
@Test
@Order(2)
public void testGetFunctionalCaseTree() throws Exception {
MvcResult mvcResult = this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL + "plan_1");
TestPlanTreeRequest request = new TestPlanTreeRequest();
request.setTestPlanId("plan_1");
request.setTreeType("MODULE");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request);
request.setTestPlanId("plan_2");
MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
this.requestGetWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL + "plan_2");
request.setTestPlanId("plan_2");
request.setTreeType("COLLECTION");
MvcResult mvcResult1 = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_URL, request);
String returnData1 = mvcResult1.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder1 = JSON.parseObject(returnData1, ResultHolder.class);
Assertions.assertNotNull(resultHolder1);
}
@Test
@Order(3)
public void testGetFunctionalCaseTreeCount() throws Exception {
TestPlanCaseRequest request = new TestPlanCaseRequest();
TestPlanCaseModuleRequest request = new TestPlanCaseModuleRequest();
request.setProjectId("123");
request.setCurrent(1);
request.setPageSize(10);
request.setTestPlanId("plan_1");
request.setTreeType("MODULE");
MvcResult mvcResult = this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_COUNT_URL, request);
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
Assertions.assertNotNull(resultHolder);
request.setTreeType("COLLECTION");
this.requestPostWithOkAndReturn(FUNCTIONAL_CASE_TREE_COUNT_URL, request);
}