feat(测试计划): 处理关联api&关联apiCase

This commit is contained in:
WangXu10 2024-06-07 10:01:13 +08:00 committed by Craftsman
parent c31b5a6ff0
commit a5065b7cb4
9 changed files with 125 additions and 32 deletions

View File

@ -2,9 +2,13 @@ package io.metersphere.plan.constants;
public class AssociateCaseType { public class AssociateCaseType {
/** /**
* 接口用例 * 接口
*/ */
public static final String API = "API"; public static final String API = "API";
/**
* 接口用例
*/
public static final String API_CASE = "API_CASE";
/** /**
* 场景用例 * 场景用例
*/ */

View File

@ -8,12 +8,10 @@ import java.util.List;
@Data @Data
public class BaseCollectionAssociateRequest { public class BaseCollectionAssociateRequest {
@Schema(description = "测试集ID") @Schema(description = "测试集ID")
private String collectionId; private String collectionId;
@Schema(description = "关联的用例ID集合") @Schema(description = "关联的用例ID集合")
private List<String> ids; private List<String> ids;
@Schema(description = "测试集类型")
private String type;
} }

View File

@ -21,7 +21,7 @@
<select id="getMaxPosByTestPlanId" resultType="java.lang.Long"> <select id="getMaxPosByTestPlanId" resultType="java.lang.Long">
SELECT max(pos) SELECT max(pos)
FROM test_plan_api_case FROM test_plan_api_case
WHERE test_plan_id = #{0} WHERE test_plan_collection_id = #{0}
</select> </select>
<select id="getIdByParam" <select id="getIdByParam"

View File

@ -1,12 +1,16 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.api.domain.ApiTestCase;
import io.metersphere.api.domain.ApiTestCaseExample;
import io.metersphere.api.dto.definition.ApiDefinitionDTO; import io.metersphere.api.dto.definition.ApiDefinitionDTO;
import io.metersphere.api.dto.definition.ApiTestCaseDTO; import io.metersphere.api.dto.definition.ApiTestCaseDTO;
import io.metersphere.api.mapper.ApiTestCaseMapper;
import io.metersphere.api.service.definition.ApiDefinitionModuleService; import io.metersphere.api.service.definition.ApiDefinitionModuleService;
import io.metersphere.api.service.definition.ApiDefinitionService; import io.metersphere.api.service.definition.ApiDefinitionService;
import io.metersphere.api.service.definition.ApiTestCaseService; import io.metersphere.api.service.definition.ApiTestCaseService;
import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO; import io.metersphere.functional.dto.FunctionalCaseModuleCountDTO;
import io.metersphere.functional.dto.ProjectOptionDTO; import io.metersphere.functional.dto.ProjectOptionDTO;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.constants.TreeTypeEnums; import io.metersphere.plan.constants.TreeTypeEnums;
import io.metersphere.plan.domain.TestPlanApiCase; import io.metersphere.plan.domain.TestPlanApiCase;
import io.metersphere.plan.domain.TestPlanApiCaseExample; import io.metersphere.plan.domain.TestPlanApiCaseExample;
@ -79,6 +83,8 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
private SqlSessionFactory sqlSessionFactory; private SqlSessionFactory sqlSessionFactory;
@Resource @Resource
private TestPlanCollectionMapper testPlanCollectionMapper; private TestPlanCollectionMapper testPlanCollectionMapper;
@Resource
private ApiTestCaseMapper apiTestCaseMapper;
@Override @Override
public void deleteBatchByTestPlanId(List<String> testPlanIdList) { public void deleteBatchByTestPlanId(List<String> testPlanIdList) {
@ -88,8 +94,13 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
} }
@Override @Override
public long getNextOrder(String projectId) { public long getNextOrder(String collectionId) {
return 0; Long maxPos = extTestPlanApiCaseMapper.getMaxPosByTestPlanId(collectionId);
if (maxPos == null) {
return 0;
} else {
return maxPos + DEFAULT_NODE_INTERVAL_POS;
}
} }
@Override @Override
@ -441,12 +452,64 @@ public class TestPlanApiCaseService extends TestPlanResourceService {
} }
@Override @Override
public void associateCollection(String planId, List<BaseCollectionAssociateRequest> collectionAssociates) { public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates, String userId) {
List<BaseCollectionAssociateRequest> apiAssociates = collectionAssociates.stream().filter(associate -> StringUtils.equals(associate.getType(), CaseType.API_CASE.getKey())).toList(); List<TestPlanApiCase> testPlanApiCaseList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(apiAssociates)) { //处理数据
apiAssociates.forEach(apiAssociate -> { handleApiData(collectionAssociates.get(AssociateCaseType.API), userId, testPlanApiCaseList, planId);
// TODO: 调用具体的关联功能用例入库方法 入参{计划ID, 测试集ID, 关联的用例ID集合} handleApiCaseData(collectionAssociates.get(AssociateCaseType.API_CASE), userId, testPlanApiCaseList, planId);
testPlanApiCaseMapper.batchInsert(testPlanApiCaseList);
}
private void handleApiCaseData(List<BaseCollectionAssociateRequest> apiCaseList, String userId, List<TestPlanApiCase> testPlanApiCaseList, String planId) {
if (CollectionUtils.isNotEmpty(apiCaseList)) {
List<String> ids = apiCaseList.stream().flatMap(item -> item.getIds().stream()).toList();
ApiTestCaseExample example = new ApiTestCaseExample();
example.createCriteria().andIdIn(ids);
List<ApiTestCase> apiTestCaseList = apiTestCaseMapper.selectByExample(example);
apiCaseList.forEach(apiCase -> {
List<String> apiCaseIds = apiCase.getIds();
List<ApiTestCase> apiTestCases = apiTestCaseList.stream().filter(item -> apiCaseIds.contains(item.getId())).collect(Collectors.toList());
buildTestPlanApiCase(planId, apiTestCases, apiCase.getCollectionId(), userId, testPlanApiCaseList);
}); });
} }
} }
private void handleApiData(List<BaseCollectionAssociateRequest> apiCaseList, String userId, List<TestPlanApiCase> testPlanApiCaseList, String planId) {
if (CollectionUtils.isNotEmpty(apiCaseList)) {
List<String> ids = apiCaseList.stream().flatMap(item -> item.getIds().stream()).toList();
ApiTestCaseExample example = new ApiTestCaseExample();
example.createCriteria().andApiDefinitionIdIn(ids);
List<ApiTestCase> apiTestCaseList = apiTestCaseMapper.selectByExample(example);
apiCaseList.forEach(apiCase -> {
List<String> apiCaseIds = apiCase.getIds();
List<ApiTestCase> apiTestCases = apiTestCaseList.stream().filter(item -> apiCaseIds.contains(item.getApiDefinitionId())).collect(Collectors.toList());
buildTestPlanApiCase(planId, apiTestCases, apiCase.getCollectionId(), userId, testPlanApiCaseList);
});
}
}
/**
* 构建测试计划接口用例对象
*
* @param planId
* @param apiTestCases
* @param collectionId
* @param userId
* @param testPlanApiCaseList
*/
private void buildTestPlanApiCase(String planId, List<ApiTestCase> apiTestCases, String collectionId, String userId, List<TestPlanApiCase> testPlanApiCaseList) {
apiTestCases.forEach(apiTestCase -> {
TestPlanApiCase testPlanApiCase = new TestPlanApiCase();
testPlanApiCase.setId(IDGenerator.nextStr());
testPlanApiCase.setTestPlanCollectionId(collectionId);
testPlanApiCase.setTestPlanId(planId);
testPlanApiCase.setApiCaseId(apiTestCase.getId());
testPlanApiCase.setEnvironmentId(apiTestCase.getEnvironmentId());
testPlanApiCase.setCreateTime(System.currentTimeMillis());
testPlanApiCase.setCreateUser(userId);
testPlanApiCase.setPos(getNextOrder(collectionId));
testPlanApiCaseList.add(testPlanApiCase);
});
}
} }

View File

@ -1,5 +1,6 @@
package io.metersphere.plan.service; package io.metersphere.plan.service;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.domain.TestPlanApiScenario; import io.metersphere.plan.domain.TestPlanApiScenario;
import io.metersphere.plan.domain.TestPlanApiScenarioExample; import io.metersphere.plan.domain.TestPlanApiScenarioExample;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount; import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
@ -96,13 +97,9 @@ public class TestPlanApiScenarioService extends TestPlanResourceService {
} }
@Override @Override
public void associateCollection(String planId, List<BaseCollectionAssociateRequest> collectionAssociates) { public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates,String userId) {
List<BaseCollectionAssociateRequest> scenarioAssociates = collectionAssociates.stream().filter(associate -> StringUtils.equals(associate.getType(), CaseType.SCENARIO_CASE.getKey())).toList(); List<BaseCollectionAssociateRequest> apiScenarios = collectionAssociates.get(AssociateCaseType.API_SCENARIO);
if (CollectionUtils.isNotEmpty(scenarioAssociates)) { // TODO: 调用具体的关联场景用例入库方法 入参{计划ID, 测试集ID, 关联的用例ID集合}
scenarioAssociates.forEach(scenarioAssociate -> {
// TODO: 调用具体的关联场景用例入库方法 入参{计划ID, 测试集ID, 关联的用例ID集合}
});
}
} }
} }

View File

@ -118,7 +118,7 @@ public class TestPlanBugService extends TestPlanResourceService {
} }
@Override @Override
public void associateCollection(String planId, List<BaseCollectionAssociateRequest> collectionAssociates) { public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates,String userId) {
// TODO: 暂不支持缺陷关联测试集 // TODO: 暂不支持缺陷关联测试集
} }
} }

View File

@ -17,6 +17,7 @@ import io.metersphere.functional.mapper.FunctionalCaseMapper;
import io.metersphere.functional.service.FunctionalCaseAttachmentService; import io.metersphere.functional.service.FunctionalCaseAttachmentService;
import io.metersphere.functional.service.FunctionalCaseModuleService; import io.metersphere.functional.service.FunctionalCaseModuleService;
import io.metersphere.functional.service.FunctionalCaseService; import io.metersphere.functional.service.FunctionalCaseService;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.domain.*; import io.metersphere.plan.domain.*;
import io.metersphere.plan.dto.ResourceLogInsertModule; import io.metersphere.plan.dto.ResourceLogInsertModule;
import io.metersphere.plan.dto.TestPlanCaseRunResultCount; import io.metersphere.plan.dto.TestPlanCaseRunResultCount;
@ -648,12 +649,8 @@ public class TestPlanFunctionalCaseService extends TestPlanResourceService {
} }
@Override @Override
public void associateCollection(String planId, List<BaseCollectionAssociateRequest> collectionAssociates) { public void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates,String userId) {
List<BaseCollectionAssociateRequest> functionalAssociates = collectionAssociates.stream().filter(associate -> StringUtils.equals(associate.getType(), CaseType.FUNCTIONAL_CASE.getKey())).toList(); List<BaseCollectionAssociateRequest> functionals = collectionAssociates.get(AssociateCaseType.FUNCTIONAL);
if (CollectionUtils.isNotEmpty(functionalAssociates)) { // TODO: 调用具体的关联接口用例入库方法 入参{计划ID, 测试集ID, 关联的用例ID集合}
functionalAssociates.forEach(functionalAssociate -> {
// TODO: 调用具体的关联接口用例入库方法 入参{计划ID, 测试集ID, 关联的用例ID集合}
});
}
} }
} }

View File

@ -57,8 +57,9 @@ public abstract class TestPlanResourceService extends TestPlanSortService {
/** /**
* 关联用例 * 关联用例
* @param planId 计划ID *
* @param planId 计划ID
* @param collectionAssociates 测试集关联用例参数 * @param collectionAssociates 测试集关联用例参数
*/ */
public abstract void associateCollection(String planId, List<BaseCollectionAssociateRequest> collectionAssociates); public abstract void associateCollection(String planId, Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates, String userId);
} }

View File

@ -1,9 +1,12 @@
package io.metersphere.plan.controller; package io.metersphere.plan.controller;
import io.metersphere.plan.constants.AssociateCaseType;
import io.metersphere.plan.dto.request.*; import io.metersphere.plan.dto.request.*;
import io.metersphere.plan.service.TestPlanApiCaseService;
import io.metersphere.sdk.util.JSON; import io.metersphere.sdk.util.JSON;
import io.metersphere.system.base.BaseTest; import io.metersphere.system.base.BaseTest;
import io.metersphere.system.controller.handler.ResultHolder; import io.metersphere.system.controller.handler.ResultHolder;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.*; import org.junit.jupiter.api.*;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@ -12,8 +15,10 @@ import org.springframework.test.context.jdbc.SqlConfig;
import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.MvcResult;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc @AutoConfigureMockMvc
@ -27,6 +32,9 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
public static final String API_CASE_BATCH_DISASSOCIATE = "/test-plan/api/case/batch/disassociate"; public static final String API_CASE_BATCH_DISASSOCIATE = "/test-plan/api/case/batch/disassociate";
public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "/test-plan/api/case/batch/update/executor"; public static final String API_CASE_BATCH_UPDATE_EXECUTOR_URL = "/test-plan/api/case/batch/update/executor";
@Resource
private TestPlanApiCaseService testPlanApiCaseService;
@Test @Test
@Order(1) @Order(1)
@Sql(scripts = {"/dml/init_test_plan_api_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED)) @Sql(scripts = {"/dml/init_test_plan_api_case.sql"}, config = @SqlConfig(encoding = "utf-8", transactionMode = SqlConfig.TransactionMode.ISOLATED))
@ -132,4 +140,29 @@ public class TestPlanApiCaseControllerTests extends BaseTest {
Assertions.assertNotNull(resultHolder); Assertions.assertNotNull(resultHolder);
} }
@Test
@Order(6)
public void testApiCaseAssociate() throws Exception {
// api
Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates = new HashMap<>();
List<BaseCollectionAssociateRequest> baseCollectionAssociateRequests = new ArrayList<>();
BaseCollectionAssociateRequest baseCollectionAssociateRequest = new BaseCollectionAssociateRequest();
baseCollectionAssociateRequest.setCollectionId("wxxx_1");
baseCollectionAssociateRequest.setIds(List.of("wxxx_api_1"));
baseCollectionAssociateRequests.add(baseCollectionAssociateRequest);
collectionAssociates.put(AssociateCaseType.API, baseCollectionAssociateRequests);
testPlanApiCaseService.associateCollection("wxxx_2", collectionAssociates, "wx");
//api case
Map<String, List<BaseCollectionAssociateRequest>> collectionAssociates1 = new HashMap<>();
List<BaseCollectionAssociateRequest> baseCollectionAssociateRequests1 = new ArrayList<>();
BaseCollectionAssociateRequest baseCollectionAssociateRequest1 = new BaseCollectionAssociateRequest();
baseCollectionAssociateRequest1.setCollectionId("wxxx_1");
baseCollectionAssociateRequest1.setIds(List.of("wxxx_api_case_1"));
baseCollectionAssociateRequests1.add(baseCollectionAssociateRequest1);
collectionAssociates1.put(AssociateCaseType.API_CASE, baseCollectionAssociateRequests1);
testPlanApiCaseService.associateCollection("wxxx_2", collectionAssociates1, "wx");
}
} }