feat(测试计划): 已关联场景模块数量接口
This commit is contained in:
parent
85a5863d4d
commit
b0cfbdd210
|
@ -2,6 +2,7 @@ package io.metersphere.plan.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiScenarioPageResponse;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioService;
|
||||
|
@ -20,6 +21,7 @@ import org.springframework.validation.annotation.Validated;
|
|||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Tag(name = "测试计划场景用例")
|
||||
@RestController
|
||||
|
@ -47,4 +49,12 @@ public class TestPlanApiScenarioController {
|
|||
StringUtils.isNotBlank(request.getSortString("id")) ? request.getSortString("id") : "create_time desc");
|
||||
return PageUtils.setPageInfo(page, testPlanApiScenarioService.hasRelateApiScenarioList(request, false));
|
||||
}
|
||||
|
||||
@PostMapping("/module/count")
|
||||
@Operation(summary = "测试计划-已关联场景用例模块数量")
|
||||
@RequiresPermissions(PermissionConstants.TEST_PLAN_READ)
|
||||
@CheckOwner(resourceId = "#request.getTestPlanId()", resourceType = "test_plan")
|
||||
public Map<String, Long> moduleCount(@Validated @RequestBody TestPlanApiScenarioModuleRequest request) {
|
||||
return testPlanApiScenarioService.moduleCount(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 TestPlanApiScenarioModuleRequest extends TestPlanApiScenarioRequest{
|
||||
|
||||
@Schema(description = "类型:模块/计划集", allowableValues = {"MODULE","COLLECTION"},requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotBlank(message = "{test_plan.type.not_blank}")
|
||||
private String treeType = TreeTypeEnums.COLLECTION;
|
||||
}
|
|
@ -559,8 +559,8 @@
|
|||
resultType="java.lang.Long">
|
||||
SELECT count(atc.id)
|
||||
FROM test_plan_api_case t
|
||||
LEFT JOIN api_test_case atc ON t.api_case_id = atc.id
|
||||
LEFT JOIN api_definition a on atc.api_definition_id = a.id
|
||||
INNER JOIN api_test_case atc ON t.api_case_id = atc.id
|
||||
INNER JOIN api_definition a on atc.api_definition_id = a.id
|
||||
WHERE t.test_plan_id = #{request.testPlanId}
|
||||
AND atc.deleted = #{deleted}
|
||||
<include refid="queryApiCaseWhereCondition"/>
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
package io.metersphere.plan.mapper;
|
||||
|
||||
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.dto.ResourceSelectParam;
|
||||
import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiScenarioPageResponse;
|
||||
import io.metersphere.project.dto.DropNode;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.project.dto.NodeSortQueryParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
|
@ -30,4 +33,12 @@ public interface ExtTestPlanApiScenarioMapper {
|
|||
List<TestPlanApiScenario> selectByTestPlanIdAndNotDeleted(String testPlanId);
|
||||
|
||||
List<TestPlanApiScenarioPageResponse> relateApiScenarioList(@Param("request") TestPlanApiScenarioRequest request, @Param("deleted") boolean deleted);
|
||||
|
||||
List<FunctionalCaseModuleCountDTO> countModuleIdByRequest(@Param("request") TestPlanApiScenarioModuleRequest request, @Param("deleted") boolean deleted);
|
||||
|
||||
long caseCount(@Param("request") TestPlanApiScenarioModuleRequest request, @Param("deleted") boolean deleted);
|
||||
|
||||
List<String> selectIdByProjectIdAndTestPlanId(@Param("projectId") String projectId, @Param("testPlanId") String testPlanId);
|
||||
|
||||
List<ModuleCountDTO> collectionCountByRequest(@Param("testPlanId") String testPlanId);
|
||||
}
|
||||
|
|
|
@ -310,4 +310,48 @@
|
|||
AND ${versionTable}.latest = 1
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
|
||||
<select id="countModuleIdByRequest" resultType="io.metersphere.functional.dto.FunctionalCaseModuleCountDTO">
|
||||
SELECT api_scenario.module_id AS moduleId, count(api_scenario.id) AS dataCount, api_scenario.project_id AS projectId, project.name AS projectName
|
||||
FROM test_plan_api_scenario
|
||||
INNER JOIN api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id
|
||||
INNER JOIN project ON api_scenario.project_id = project.id
|
||||
WHERE test_plan_api_scenario.test_plan_id = #{request.testPlanId}
|
||||
AND api_scenario.deleted = #{deleted}
|
||||
<include refid="queryApiScenarioWhereCondition"/>
|
||||
GROUP BY module_id
|
||||
</select>
|
||||
|
||||
<select id="caseCount"
|
||||
resultType="java.lang.Long">
|
||||
SELECT count(api_scenario.id)
|
||||
FROM test_plan_api_scenario
|
||||
INNER JOIN api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id
|
||||
WHERE test_plan_api_scenario.test_plan_id = #{request.testPlanId}
|
||||
AND api_scenario.deleted = #{deleted}
|
||||
<include refid="queryApiScenarioWhereCondition"/>
|
||||
</select>
|
||||
|
||||
<select id="selectIdByProjectIdAndTestPlanId" resultType="java.lang.String">
|
||||
SELECT asm.id, asm.project_id
|
||||
FROM api_scenario_module asm
|
||||
WHERE asm.id IN (
|
||||
SELECT api_scenario.module_id FROM api_scenario LEFT JOIN test_plan_api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id WHERE test_plan_api_scenario.test_plan_id = #{testPlanId} AND api_scenario.deleted = false and api_scenario.project_id = #{projectId}
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="collectionCountByRequest" parameterType="java.lang.String" resultType="io.metersphere.project.dto.ModuleCountDTO">
|
||||
SELECT
|
||||
test_plan_api_scenario.test_plan_collection_id AS moduleId,
|
||||
count( test_plan_api_scenario.id ) AS dataCount
|
||||
FROM
|
||||
api_scenario
|
||||
INNER JOIN test_plan_api_scenario on api_scenario.id = test_plan_api_scenario.api_scenario_id
|
||||
WHERE
|
||||
api_scenario.deleted = FALSE
|
||||
AND test_plan_api_scenario.test_plan_id = #{testPlanId}
|
||||
GROUP BY
|
||||
test_plan_api_scenario.test_plan_collection_id
|
||||
</select>
|
||||
</mapper>
|
|
@ -6,9 +6,12 @@ import io.metersphere.api.dto.scenario.ApiScenarioDTO;
|
|||
import io.metersphere.api.invoker.GetRunScriptServiceRegister;
|
||||
import io.metersphere.api.service.ApiExecuteService;
|
||||
import io.metersphere.api.service.GetRunScriptService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioModuleService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioRunService;
|
||||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
|
||||
import io.metersphere.plan.constants.AssociateCaseType;
|
||||
import io.metersphere.plan.constants.TreeTypeEnums;
|
||||
import io.metersphere.plan.domain.TestPlan;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenarioExample;
|
||||
|
@ -18,12 +21,14 @@ import io.metersphere.plan.dto.TestPlanCollectionDTO;
|
|||
import io.metersphere.plan.dto.TestPlanCollectionEnvDTO;
|
||||
import io.metersphere.plan.dto.request.BaseCollectionAssociateRequest;
|
||||
import io.metersphere.plan.dto.request.ResourceSortRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.dto.response.TestPlanApiScenarioPageResponse;
|
||||
import io.metersphere.plan.dto.response.TestPlanOperationResponse;
|
||||
import io.metersphere.plan.mapper.*;
|
||||
import io.metersphere.project.domain.Project;
|
||||
import io.metersphere.project.domain.ProjectExample;
|
||||
import io.metersphere.project.dto.ModuleCountDTO;
|
||||
import io.metersphere.project.dto.MoveNodeSortDTO;
|
||||
import io.metersphere.project.mapper.ProjectMapper;
|
||||
import io.metersphere.sdk.constants.*;
|
||||
|
@ -35,6 +40,7 @@ import io.metersphere.sdk.mapper.EnvironmentMapper;
|
|||
import io.metersphere.sdk.util.BeanUtils;
|
||||
import io.metersphere.sdk.util.Translator;
|
||||
import io.metersphere.system.dto.LogInsertModule;
|
||||
import io.metersphere.system.dto.sdk.BaseTreeNode;
|
||||
import io.metersphere.system.service.UserLoginService;
|
||||
import io.metersphere.system.uid.IDGenerator;
|
||||
import io.metersphere.system.utils.ServiceUtils;
|
||||
|
@ -49,6 +55,7 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -80,6 +87,9 @@ public class TestPlanApiScenarioService extends TestPlanResourceService implemen
|
|||
private ExtTestPlanCollectionMapper extTestPlanCollectionMapper;
|
||||
@Resource
|
||||
private EnvironmentMapper environmentMapper;
|
||||
private static final String CASE_MODULE_COUNT_ALL = "all";
|
||||
@Resource
|
||||
private ApiScenarioModuleService apiScenarioModuleService;
|
||||
|
||||
public TestPlanApiScenarioService() {
|
||||
GetRunScriptServiceRegister.register(ApiExecuteResourceType.TEST_PLAN_API_SCENARIO, this);
|
||||
|
@ -334,4 +344,80 @@ public class TestPlanApiScenarioService extends TestPlanResourceService implemen
|
|||
List<Project> projectList = projectMapper.selectByExample(projectExample);
|
||||
return projectList.stream().collect(Collectors.toMap(Project::getId, Project::getName));
|
||||
}
|
||||
|
||||
public Map<String, Long> moduleCount(TestPlanApiScenarioModuleRequest 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(TestPlanApiScenarioModuleRequest request) {
|
||||
Map<String, Long> projectModuleCountMap = new HashMap<>();
|
||||
List<ModuleCountDTO> list = extTestPlanApiScenarioMapper.collectionCountByRequest(request.getTestPlanId());
|
||||
list.forEach(item -> {
|
||||
projectModuleCountMap.put(item.getModuleId(), (long) item.getDataCount());
|
||||
});
|
||||
long allCount = extTestPlanApiScenarioMapper.caseCount(request, false);
|
||||
projectModuleCountMap.put(CASE_MODULE_COUNT_ALL, allCount);
|
||||
return projectModuleCountMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已关联场景 模块树统计
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Long> getModuleCount(TestPlanApiScenarioModuleRequest request) {
|
||||
request.setModuleIds(null);
|
||||
List<FunctionalCaseModuleCountDTO> projectModuleCountDTOList = extTestPlanApiScenarioMapper.countModuleIdByRequest(request, false);
|
||||
Map<String, List<FunctionalCaseModuleCountDTO>> projectCountMap = projectModuleCountDTOList.stream().collect(Collectors.groupingBy(FunctionalCaseModuleCountDTO::getProjectId));
|
||||
Map<String, Long> projectModuleCountMap = new HashMap<>();
|
||||
projectCountMap.forEach((projectId, moduleCountDTOList) -> {
|
||||
List<ModuleCountDTO> moduleCountDTOS = new ArrayList<>();
|
||||
for (FunctionalCaseModuleCountDTO functionalCaseModuleCountDTO : moduleCountDTOList) {
|
||||
ModuleCountDTO moduleCountDTO = new ModuleCountDTO();
|
||||
BeanUtils.copyBean(moduleCountDTO, functionalCaseModuleCountDTO);
|
||||
moduleCountDTOS.add(moduleCountDTO);
|
||||
}
|
||||
int sum = moduleCountDTOList.stream().mapToInt(FunctionalCaseModuleCountDTO::getDataCount).sum();
|
||||
Map<String, Long> moduleCountMap = getModuleCountMap(projectId, request.getTestPlanId(), moduleCountDTOS);
|
||||
moduleCountMap.forEach((k, v) -> {
|
||||
if (projectModuleCountMap.get(k) == null || projectModuleCountMap.get(k) == 0L) {
|
||||
projectModuleCountMap.put(k, v);
|
||||
}
|
||||
});
|
||||
projectModuleCountMap.put(projectId, (long) sum);
|
||||
});
|
||||
//查出全部用例数量
|
||||
long allCount = extTestPlanApiScenarioMapper.caseCount(request, false);
|
||||
projectModuleCountMap.put(CASE_MODULE_COUNT_ALL, allCount);
|
||||
return projectModuleCountMap;
|
||||
}
|
||||
|
||||
private Map<String, Long> getModuleCountMap(String projectId, String testPlanId, List<ModuleCountDTO> moduleCountDTOList) {
|
||||
//构建模块树,并计算每个节点下的所有数量(包含子节点)
|
||||
List<BaseTreeNode> treeNodeList = this.getTreeOnlyIdsAndResourceCount(projectId, testPlanId, moduleCountDTOList);
|
||||
//通过广度遍历的方式构建返回值
|
||||
return apiScenarioModuleService.getIdCountMapByBreadth(treeNodeList);
|
||||
}
|
||||
|
||||
public List<BaseTreeNode> getTreeOnlyIdsAndResourceCount(String projectId, String testPlanId, List<ModuleCountDTO> moduleCountDTOList) {
|
||||
//节点内容只有Id和parentId
|
||||
List<String> moduleIds = extTestPlanApiScenarioMapper.selectIdByProjectIdAndTestPlanId(projectId, testPlanId);
|
||||
List<BaseTreeNode> nodeByNodeIds = apiScenarioModuleService.getNodeByNodeIds(moduleIds);
|
||||
return apiScenarioModuleService.buildTreeAndCountResource(nodeByNodeIds, moduleCountDTOList, true, Translator.get("functional_case.module.default.name"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import io.metersphere.api.dto.scenario.ScenarioOtherConfig;
|
|||
import io.metersphere.api.service.scenario.ApiScenarioService;
|
||||
import io.metersphere.api.utils.ApiDataUtils;
|
||||
import io.metersphere.plan.domain.TestPlanApiScenario;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiCaseRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioModuleRequest;
|
||||
import io.metersphere.plan.dto.request.TestPlanApiScenarioRequest;
|
||||
import io.metersphere.plan.mapper.TestPlanApiScenarioMapper;
|
||||
import io.metersphere.plan.service.TestPlanApiScenarioService;
|
||||
|
@ -55,6 +55,7 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
public static final String RUN = "run/{0}";
|
||||
public static final String RUN_WITH_REPORT_ID = "run/{0}?reportId={1}";
|
||||
public static final String API_SCENARIO_PAGE = "page";
|
||||
public static final String API_SCENARIO_TREE_COUNT = "module/count";
|
||||
|
||||
@Resource
|
||||
private TestPlanApiScenarioService testPlanApiScenarioService;
|
||||
|
@ -179,7 +180,6 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
@Sql(scripts = {"/dml/init_test_plan_api_scenario.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
|
||||
|
@ -198,4 +198,24 @@ public class TestPlanApiScenarioControllerTests extends BaseTest {
|
|||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void testApiCaseCount() throws Exception {
|
||||
TestPlanApiScenarioModuleRequest request = new TestPlanApiScenarioModuleRequest();
|
||||
request.setTestPlanId("wxxx_plan_1");
|
||||
request.setProjectId("wxx_project_1234");
|
||||
request.setCurrent(1);
|
||||
request.setPageSize(10);
|
||||
request.setTreeType("MODULE");
|
||||
MvcResult mvcResult = this.requestPostWithOkAndReturn(API_SCENARIO_TREE_COUNT, request);
|
||||
String returnData = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
|
||||
ResultHolder resultHolder = JSON.parseObject(returnData, ResultHolder.class);
|
||||
Assertions.assertNotNull(resultHolder);
|
||||
|
||||
request.setTreeType("COLLECTION");
|
||||
this.requestPostWithOkAndReturn(API_SCENARIO_TREE_COUNT, request);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue