fix(接口测试): 修复场景导入引用用例id与生成的用例ID不一致问题

https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001018447
https://www.tapd.cn/55049933/bugtrace/bugs/view/1155049933001018451
--user=郭雨琦
This commit is contained in:
guoyuqi 2022-10-19 18:49:46 +08:00 committed by xiaomeinvG
parent 512ad83158
commit 8a81279a7c
3 changed files with 89 additions and 66 deletions

View File

@ -22,6 +22,7 @@ import io.metersphere.service.BaseCheckPermissionService;
import io.metersphere.service.definition.ApiDefinitionService; import io.metersphere.service.definition.ApiDefinitionService;
import io.metersphere.service.definition.ApiTestCaseService; import io.metersphere.service.definition.ApiTestCaseService;
import io.metersphere.service.scenario.ApiScenarioModuleService; import io.metersphere.service.scenario.ApiScenarioModuleService;
import io.metersphere.service.scenario.dto.ApiScenarioParamDto;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils; import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -160,7 +161,10 @@ public class ApiScenarioImportUtil {
} }
} }
public static void checkCase(JSONObject object, String versionId, String projectId, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper, Map<String, ApiDefinition> definitionMap,Map<String, Set<String>> apiIdCaseNameMap) { public static void checkCase(JSONObject object, String versionId, String projectId, ApiScenarioParamDto apiScenarioParamDto) {
Map<String, ApiDefinition> definitionMap = apiScenarioParamDto.getDefinitionMap();
ApiTestCaseMapper apiTestCaseMapper = apiScenarioParamDto.getApiTestCaseMapper();
Map<String, Set<String>> apiIdCaseNameMap = apiScenarioParamDto.getApiIdCaseNameMap();
ApiTestCaseService testCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class); ApiTestCaseService testCaseService = CommonBeanFactory.getBean(ApiTestCaseService.class);
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class); ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
ApiTestCaseWithBLOBs bloBs = testCaseService.get(object.optString("id")); ApiTestCaseWithBLOBs bloBs = testCaseService.get(object.optString("id"));
@ -185,7 +189,7 @@ public class ApiScenarioImportUtil {
} }
} }
} else { } else {
ApiDefinitionResult apiDefinitionResult = structureApiDefinitionByJson(apiDefinitionService, object, versionId, projectId, apiDefinitionMapper, definitionMap); ApiDefinitionResult apiDefinitionResult = structureApiDefinitionByJson(apiDefinitionService, object, versionId, projectId, apiScenarioParamDto.getApiDefinitionMapper(), definitionMap);
structureCaseByJson(object, testCaseService, apiDefinitionResult, apiTestCaseMapper,apiIdCaseNameMap); structureCaseByJson(object, testCaseService, apiDefinitionResult, apiTestCaseMapper,apiIdCaseNameMap);
} }
} }

View File

@ -53,6 +53,7 @@ import io.metersphere.service.definition.EsbApiParamService;
import io.metersphere.service.definition.TcpApiParamService; import io.metersphere.service.definition.TcpApiParamService;
import io.metersphere.service.ext.ExtApiScheduleService; import io.metersphere.service.ext.ExtApiScheduleService;
import io.metersphere.service.ext.ExtFileAssociationService; import io.metersphere.service.ext.ExtFileAssociationService;
import io.metersphere.service.scenario.dto.ApiScenarioParamDto;
import io.metersphere.xpack.api.service.ApiAutomationRelationshipEdgeService; import io.metersphere.xpack.api.service.ApiAutomationRelationshipEdgeService;
import io.metersphere.xpack.quota.service.QuotaService; import io.metersphere.xpack.quota.service.QuotaService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -65,6 +66,7 @@ import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.jorphan.collections.HashTree; import org.apache.jorphan.collections.HashTree;
import org.apache.jorphan.collections.ListedHashTree; import org.apache.jorphan.collections.ListedHashTree;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.mybatis.spring.SqlSessionUtils; import org.mybatis.spring.SqlSessionUtils;
@ -401,14 +403,14 @@ public class ApiScenarioService {
return scenario; return scenario;
} }
private void checkReferenceCase(ApiScenarioWithBLOBs scenario) { private void checkReferenceCase(ApiScenarioWithBLOBs scenario, ApiScenarioParamDto apiScenarioParamDto) {
if (scenario == null || StringUtils.isEmpty(scenario.getScenarioDefinition())) { if (scenario == null || StringUtils.isEmpty(scenario.getScenarioDefinition())) {
return; return;
} }
JSONObject element = JSONUtil.parseObject(scenario.getScenarioDefinition()); JSONObject element = JSONUtil.parseObject(scenario.getScenarioDefinition());
JSONArray hashTree = element.optJSONArray(ElementConstants.HASH_TREE); JSONArray hashTree = element.optJSONArray(ElementConstants.HASH_TREE);
ApiScenarioImportUtil.formatHashTree(hashTree); ApiScenarioImportUtil.formatHashTree(hashTree);
setReferenced(hashTree, scenario.getProjectId()); setReferenced(hashTree, scenario.getProjectId(), scenario.getVersionId(), apiScenarioParamDto);
scenario.setScenarioDefinition(element.toString()); scenario.setScenarioDefinition(element.toString());
} }
@ -585,13 +587,13 @@ public class ApiScenarioService {
} }
public void removeToGc(List<String> apiIds) { public void removeToGc(List<String> apiIds) {
if (CollectionUtils.isEmpty(apiIds)){ if (CollectionUtils.isEmpty(apiIds)) {
return; return;
} }
ApiScenarioExample apiScenarioExample = new ApiScenarioExample(); ApiScenarioExample apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andIdIn(apiIds); apiScenarioExample.createCriteria().andIdIn(apiIds);
List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(apiScenarioExample); List<ApiScenario> apiScenarios = apiScenarioMapper.selectByExample(apiScenarioExample);
if (CollectionUtils.isEmpty(apiScenarios)){ if (CollectionUtils.isEmpty(apiScenarios)) {
return; return;
} }
@ -600,7 +602,7 @@ public class ApiScenarioService {
apiScenarioExample = new ApiScenarioExample(); apiScenarioExample = new ApiScenarioExample();
apiScenarioExample.createCriteria().andRefIdIn(refIds); apiScenarioExample.createCriteria().andRefIdIn(refIds);
List<ApiScenario> apiScenarioVersions = apiScenarioMapper.selectByExample(apiScenarioExample); List<ApiScenario> apiScenarioVersions = apiScenarioMapper.selectByExample(apiScenarioExample);
if (CollectionUtils.isEmpty(apiScenarioVersions)){ if (CollectionUtils.isEmpty(apiScenarioVersions)) {
return; return;
} }
List<String> scenarioIds = apiScenarioVersions.stream().map(ApiScenario::getId).collect(toList()); List<String> scenarioIds = apiScenarioVersions.stream().map(ApiScenario::getId).collect(toList());
@ -1167,7 +1169,9 @@ public class ApiScenarioService {
} }
} }
private void _importCreate(List<ApiScenarioWithBLOBs> sameRequest, ApiScenarioMapper batchMapper, ExtApiScenarioMapper extApiScenarioMapper, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest) { private void _importCreate(List<ApiScenarioWithBLOBs> sameRequest, ApiScenarioWithBLOBs scenarioWithBLOBs, ApiTestImportRequest apiTestImportRequest, ApiScenarioParamDto apiScenarioParamDto) {
ApiScenarioMapper batchMapper = apiScenarioParamDto.getBatchMapper();
ExtApiScenarioMapper extApiScenarioMapper = apiScenarioParamDto.getExtApiScenarioMapper();
if (CollectionUtils.isEmpty(sameRequest)) { if (CollectionUtils.isEmpty(sameRequest)) {
// 没有这个场景 新增 // 没有这个场景 新增
scenarioWithBLOBs.setId(UUID.randomUUID().toString()); scenarioWithBLOBs.setId(UUID.randomUUID().toString());
@ -1190,7 +1194,7 @@ public class ApiScenarioService {
} }
} }
checkReferenceCase(scenarioWithBLOBs); checkReferenceCase(scenarioWithBLOBs, apiScenarioParamDto);
sendImportScenarioCreateNotice(scenarioWithBLOBs); sendImportScenarioCreateNotice(scenarioWithBLOBs);
batchMapper.insert(scenarioWithBLOBs); batchMapper.insert(scenarioWithBLOBs);
apiScenarioReferenceIdService.saveApiAndScenarioRelation(scenarioWithBLOBs); apiScenarioReferenceIdService.saveApiAndScenarioRelation(scenarioWithBLOBs);
@ -1212,7 +1216,7 @@ public class ApiScenarioService {
scenarioWithBLOBs.setRefId(sameRequest.get(0).getRefId() == null ? sameRequest.get(0).getId() : sameRequest.get(0).getRefId()); scenarioWithBLOBs.setRefId(sameRequest.get(0).getRefId() == null ? sameRequest.get(0).getId() : sameRequest.get(0).getRefId());
scenarioWithBLOBs.setNum(sameRequest.get(0).getNum()); // 使用第一个num当作本次的num scenarioWithBLOBs.setNum(sameRequest.get(0).getNum()); // 使用第一个num当作本次的num
scenarioWithBLOBs.setOrder(sameRequest.get(0).getOrder()); scenarioWithBLOBs.setOrder(sameRequest.get(0).getOrder());
checkReferenceCase(scenarioWithBLOBs); checkReferenceCase(scenarioWithBLOBs, apiScenarioParamDto);
sendImportScenarioCreateNotice(scenarioWithBLOBs); sendImportScenarioCreateNotice(scenarioWithBLOBs);
batchMapper.insert(scenarioWithBLOBs); batchMapper.insert(scenarioWithBLOBs);
} else { } else {
@ -1222,7 +1226,7 @@ public class ApiScenarioService {
scenarioWithBLOBs.setVersionId(apiTestImportRequest.getUpdateVersionId()); scenarioWithBLOBs.setVersionId(apiTestImportRequest.getUpdateVersionId());
scenarioWithBLOBs.setOrder(existScenario.getOrder()); scenarioWithBLOBs.setOrder(existScenario.getOrder());
scenarioWithBLOBs.setNum(existScenario.getNum()); scenarioWithBLOBs.setNum(existScenario.getNum());
checkReferenceCase(scenarioWithBLOBs); checkReferenceCase(scenarioWithBLOBs, apiScenarioParamDto);
sendImportScenarioUpdateNotice(scenarioWithBLOBs); sendImportScenarioUpdateNotice(scenarioWithBLOBs);
batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs); batchMapper.updateByPrimaryKeyWithBLOBs(scenarioWithBLOBs);
} }
@ -1232,8 +1236,10 @@ public class ApiScenarioService {
} }
} }
private ApiScenarioWithBLOBs importCreate(ApiScenarioWithBLOBs request, ApiScenarioMapper batchMapper, ExtApiScenarioMapper extApiScenarioMapper, ApiTestImportRequest apiTestImportRequest, List<ApiScenarioWithBLOBs> sameList) { private ApiScenarioWithBLOBs importCreate(ApiScenarioWithBLOBs request, ApiTestImportRequest apiTestImportRequest, List<ApiScenarioWithBLOBs> sameList, ApiScenarioParamDto apiScenarioParamDto) {
final ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs(); final ApiScenarioWithBLOBs scenarioWithBLOBs = new ApiScenarioWithBLOBs();
ApiScenarioMapper batchMapper = apiScenarioParamDto.getBatchMapper();
ExtApiScenarioMapper extApiScenarioMapper = apiScenarioParamDto.getExtApiScenarioMapper();
BeanUtils.copyBean(scenarioWithBLOBs, request); BeanUtils.copyBean(scenarioWithBLOBs, request);
scenarioWithBLOBs.setUpdateTime(System.currentTimeMillis()); scenarioWithBLOBs.setUpdateTime(System.currentTimeMillis());
if (StringUtils.isEmpty(scenarioWithBLOBs.getStatus())) { if (StringUtils.isEmpty(scenarioWithBLOBs.getStatus())) {
@ -1276,9 +1282,8 @@ public class ApiScenarioService {
} }
if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) { if (StringUtils.equals("fullCoverage", apiTestImportRequest.getModeId())) {
_importCreate(sameList, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest); _importCreate(sameList, scenarioWithBLOBs, apiTestImportRequest, apiScenarioParamDto);
} } else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
else if (StringUtils.equals("incrementalMerge", apiTestImportRequest.getModeId())) {
scenarioWithBLOBs.setId(UUID.randomUUID().toString()); scenarioWithBLOBs.setId(UUID.randomUUID().toString());
scenarioWithBLOBs.setCreateTime(System.currentTimeMillis()); scenarioWithBLOBs.setCreateTime(System.currentTimeMillis());
if (CollectionUtils.isEmpty(sameList)) { if (CollectionUtils.isEmpty(sameList)) {
@ -1303,7 +1308,7 @@ public class ApiScenarioService {
if (scenarioWithBLOBs.getRefId() == null) { if (scenarioWithBLOBs.getRefId() == null) {
scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId()); scenarioWithBLOBs.setRefId(scenarioWithBLOBs.getId());
} }
checkReferenceCase(scenarioWithBLOBs); checkReferenceCase(scenarioWithBLOBs, apiScenarioParamDto);
sendImportScenarioCreateNotice(scenarioWithBLOBs); sendImportScenarioCreateNotice(scenarioWithBLOBs);
batchMapper.insert(scenarioWithBLOBs); batchMapper.insert(scenarioWithBLOBs);
// 存储依赖关系 // 存储依赖关系
@ -1317,7 +1322,7 @@ public class ApiScenarioService {
} }
} else { } else {
_importCreate(sameList, batchMapper, extApiScenarioMapper, scenarioWithBLOBs, apiTestImportRequest); _importCreate(sameList, scenarioWithBLOBs, apiTestImportRequest, apiScenarioParamDto);
} }
return scenarioWithBLOBs; return scenarioWithBLOBs;
} }
@ -1424,13 +1429,9 @@ public class ApiScenarioService {
item.setUserId(SessionUtils.getUserId()); item.setUserId(SessionUtils.getUserId());
item.setPrincipal(SessionUtils.getUserId()); item.setPrincipal(SessionUtils.getUserId());
// 导入之后刷新latest // 导入之后刷新latest
ApiScenarioWithBLOBs apiScenarioWithBLOBs = importCreate(item, batchMapper, extApiScenarioMapper, request, sameList); ApiScenarioParamDto apiScenarioParamDto = buildParamDto(batchMapper, extApiScenarioMapper, apiTestCaseMapper, apiDefinitionMapper, definitionMap, apiIdCaseNameMap);
JSONObject element = JSONUtil.parseObject(apiScenarioWithBLOBs.getScenarioDefinition()); importCreate(item, request, sameList, apiScenarioParamDto);
JSONArray hashTree = element.optJSONArray(ElementConstants.HASH_TREE);
ApiScenarioImportUtil.formatHashTree(hashTree);
String projectId = apiScenarioWithBLOBs.getProjectId();
String versionId = apiScenarioWithBLOBs.getVersionId();
creatCase(apiTestCaseMapper, apiDefinitionMapper, definitionMap, hashTree, projectId, versionId,apiIdCaseNameMap);
if (i % 300 == 0) { if (i % 300 == 0) {
sqlSession.flushStatements(); sqlSession.flushStatements();
} }
@ -1442,24 +1443,19 @@ public class ApiScenarioService {
} }
} }
private void creatCase(ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper, Map<String, ApiDefinition> definitionMap, JSONArray hashTree, String projectId, String versionId,Map<String, Set<String>> apiIdCaseNameMap) { @NotNull
if (hashTree==null) { private static ApiScenarioParamDto buildParamDto(ApiScenarioMapper batchMapper, ExtApiScenarioMapper extApiScenarioMapper, ApiTestCaseMapper apiTestCaseMapper, ApiDefinitionMapper apiDefinitionMapper, Map<String, ApiDefinition> definitionMap, Map<String, Set<String>> apiIdCaseNameMap) {
return; ApiScenarioParamDto apiScenarioParamDto = new ApiScenarioParamDto();
} apiScenarioParamDto.setBatchMapper(batchMapper);
for (int i = 0; i < hashTree.length(); i++) { apiScenarioParamDto.setExtApiScenarioMapper(extApiScenarioMapper);
JSONObject object = (JSONObject) hashTree.get(i); apiScenarioParamDto.setApiTestCaseMapper(apiTestCaseMapper);
String referenced = object.optString("referenced"); apiScenarioParamDto.setApiDefinitionMapper(apiDefinitionMapper);
if (StringUtils.isNotBlank(referenced) && StringUtils.equals(referenced, "REF")) { apiScenarioParamDto.setDefinitionMap(definitionMap);
// 检测引用对象是否存在若果不存在则改成复制对象 apiScenarioParamDto.setApiIdCaseNameMap(apiIdCaseNameMap);
String refType = object.optString("refType"); return apiScenarioParamDto;
if (StringUtils.isNotEmpty(refType) && refType.equals("CASE")) {
ApiScenarioImportUtil.checkCase(object, versionId, projectId, apiTestCaseMapper, apiDefinitionMapper, definitionMap,apiIdCaseNameMap);
}
}
creatCase(apiTestCaseMapper,apiDefinitionMapper,definitionMap,object.optJSONArray(ElementConstants.HASH_TREE), projectId,versionId, apiIdCaseNameMap);
}
} }
private void replenishScenarioModuleIdPath(String request, ApiScenarioModuleMapper apiScenarioModuleMapper, ApiScenarioWithBLOBs item) { private void replenishScenarioModuleIdPath(String request, ApiScenarioModuleMapper apiScenarioModuleMapper, ApiScenarioWithBLOBs item) {
ApiScenarioModuleExample example = new ApiScenarioModuleExample(); ApiScenarioModuleExample example = new ApiScenarioModuleExample();
example.createCriteria().andProjectIdEqualTo(request).andNameEqualTo("未规划场景"); example.createCriteria().andProjectIdEqualTo(request).andNameEqualTo("未规划场景");
@ -2108,39 +2104,41 @@ public class ApiScenarioService {
return strings; return strings;
} }
private void setReferenced(JSONArray hashTree, String projectId) { private void setReferenced(JSONArray hashTree, String projectId, String versionId, ApiScenarioParamDto apiScenarioParamDto) {
// 将引用转成复制 // 将引用转成复制
if (hashTree != null) { if (hashTree == null) {
for (int i = 0; i < hashTree.length(); i++) { return;
JSONObject object = (JSONObject) hashTree.get(i); }
String referenced = object.optString("referenced"); for (int i = 0; i < hashTree.length(); i++) {
if (StringUtils.isNotBlank(referenced) && StringUtils.equals(referenced, "REF")) { JSONObject object = (JSONObject) hashTree.get(i);
// 检测引用对象是否存在若果不存在则改成复制对象 String referenced = object.optString("referenced");
String refType = object.optString("refType"); if (StringUtils.isNotBlank(referenced) && StringUtils.equals(referenced, "REF")) {
if (StringUtils.isNotEmpty(refType)) { // 检测引用对象是否存在若果不存在则改成复制对象
if (!refType.equals("CASE")){ String refType = object.optString("refType");
checkAutomation(object); if (StringUtils.isNotEmpty(refType)) {
object.put("projectId", projectId); if (refType.equals("CASE")) {
} ApiScenarioImportUtil.checkCase(object, versionId, projectId, apiScenarioParamDto);
} else { } else {
object.put("referenced", "Copy"); checkAutomation(object);
object.put("projectId", projectId);
} }
} else { } else {
object.put("projectId", projectId); object.put("referenced", "Copy");
if (StringUtils.isEmpty(object.optString("url"))) {
object.put("isRefEnvironment", true);
}
} }
JSONObject environmentMap = null; } else {
if (object.has("environmentMap")) { object.put("projectId", projectId);
environmentMap = object.optJSONObject("environmentMap"); if (StringUtils.isEmpty(object.optString("url"))) {
object.put("isRefEnvironment", true);
} }
if (environmentMap != null) {
object.put("environmentMap", new HashMap<>());
}
setReferenced(object.optJSONArray(ElementConstants.HASH_TREE), projectId);
} }
JSONObject environmentMap = null;
if (object.has("environmentMap")) {
environmentMap = object.optJSONObject("environmentMap");
}
if (environmentMap != null) {
object.put("environmentMap", new HashMap<>());
}
setReferenced(object.optJSONArray(ElementConstants.HASH_TREE), projectId, versionId, apiScenarioParamDto);
} }
} }

View File

@ -0,0 +1,21 @@
package io.metersphere.service.scenario.dto;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.mapper.ApiDefinitionMapper;
import io.metersphere.base.mapper.ApiScenarioMapper;
import io.metersphere.base.mapper.ApiTestCaseMapper;
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
import lombok.Data;
import java.util.Map;
import java.util.Set;
@Data
public class ApiScenarioParamDto {
private ApiScenarioMapper batchMapper;
private ExtApiScenarioMapper extApiScenarioMapper;
private ApiTestCaseMapper apiTestCaseMapper;
private ApiDefinitionMapper apiDefinitionMapper;
private Map<String, ApiDefinition> definitionMap;
private Map<String, Set<String>> apiIdCaseNameMap;
}