fix(接口测试): 修复修改case的前后置操作,测试计划执行未同步的缺陷
--bug=1028019 --user=王孝刚 【测试跟踪】github#25703,测试计划关联场景,场景中引用了case, case 修改,测试计划执行未同步更新 https://www.tapd.cn/55049933/s/1397246
This commit is contained in:
parent
7c3e5b7d02
commit
c57c49da6c
|
@ -74,11 +74,9 @@ import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class ElementUtil {
|
public class ElementUtil {
|
||||||
private static final String PRE = "PRE";
|
private static final String PRE = "PRE";
|
||||||
|
@ -443,51 +441,126 @@ public class ElementUtil {
|
||||||
element.setHashTree(targetHashTree);
|
element.setHashTree(targetHashTree);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 合并步骤
|
Map<String, LinkedList<MsTestElement>> source = groupCase(element.getHashTree());
|
||||||
List<MsTestElement> sourceList = Stream.of(element.getHashTree(), targetHashTree)
|
Map<String, LinkedList<MsTestElement>> target = groupCase(targetHashTree);
|
||||||
.flatMap(Collection::stream)
|
List<MsTestElement> pre = ElementUtil.mergeCaseHashTree(source.get(PRE), target.get(PRE));
|
||||||
.distinct()
|
List<MsTestElement> post = ElementUtil.mergeCaseHashTree(source.get(POST), target.get(POST));
|
||||||
.collect(Collectors.toList());
|
List<MsTestElement> rules = mergeCaseHashTree(source.get(ASSERTIONS), target.get(ASSERTIONS));
|
||||||
|
List<MsTestElement> step = new LinkedList<>();
|
||||||
// 历史数据补充id
|
if (CollectionUtils.isNotEmpty(pre)) {
|
||||||
sourceList.forEach(item -> {
|
step.addAll(pre);
|
||||||
if (StringUtils.isBlank(item.getId())) {
|
|
||||||
item.setId(UUID.randomUUID().toString());
|
|
||||||
}
|
}
|
||||||
});
|
if (CollectionUtils.isNotEmpty(post)) {
|
||||||
|
step.addAll(post);
|
||||||
|
|
||||||
//对sourceList根据id去重并且保持原有顺序
|
|
||||||
sourceList = sourceList.stream()
|
|
||||||
.collect(Collectors.toMap(MsTestElement::getId, Function.identity(), (oldValue, newValue) -> oldValue, LinkedHashMap::new))
|
|
||||||
.values()
|
|
||||||
.stream()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
|
|
||||||
//删除不需要的元素
|
|
||||||
for (int i = 0; i < sourceList.size(); i++) {
|
|
||||||
MsTestElement item = sourceList.get(i);
|
|
||||||
if (!StringUtils.equals(item.getLabel(), SCENARIO_REF)
|
|
||||||
&& targetHashTree.stream().noneMatch(target -> StringUtils.equals(target.getId(), item.getId()))) {
|
|
||||||
sourceList.remove(i);
|
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(rules)) {
|
||||||
|
step.addAll(rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
element.getHashTree().clear();
|
element.getHashTree().clear();
|
||||||
element.getHashTree().addAll(sourceList);
|
element.getHashTree().addAll(step);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
element.setHashTree(targetHashTree);
|
element.setHashTree(targetHashTree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<JSONObject> mergeHashTree(List<JSONObject> sources, List<JSONObject> targets) {
|
public static Map<String, LinkedList<MsTestElement>> groupCase(List<MsTestElement> elements) {
|
||||||
|
Map<String, LinkedList<MsTestElement>> groupMap = new LinkedHashMap<>();
|
||||||
|
if (elements != null) {
|
||||||
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
|
MsTestElement item = elements.get(i);
|
||||||
|
if (ElementConstants.ASSERTIONS.equals(item.getType())) {
|
||||||
|
if (groupMap.containsKey(ASSERTIONS)) {
|
||||||
|
groupMap.get(ASSERTIONS).add(item);
|
||||||
|
} else {
|
||||||
|
groupMap.put(ASSERTIONS, new LinkedList<MsTestElement>() {{
|
||||||
|
this.add(item);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
} else if (preOperates.contains(item.getType())) {
|
||||||
|
if (groupMap.containsKey(PRE)) {
|
||||||
|
groupMap.get(PRE).add(item);
|
||||||
|
} else {
|
||||||
|
groupMap.put(PRE, new LinkedList<MsTestElement>() {{
|
||||||
|
this.add(item);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
} else if (postOperates.contains(item.getType())) {
|
||||||
|
if (groupMap.containsKey(POST)) {
|
||||||
|
groupMap.get(POST).add(item);
|
||||||
|
} else {
|
||||||
|
groupMap.put(POST, new LinkedList<MsTestElement>() {{
|
||||||
|
this.add(item);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return groupMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static List<MsTestElement> mergeCaseHashTree(List<MsTestElement> targets, List<MsTestElement> sources) {
|
||||||
|
try {
|
||||||
|
List<String> sourceIds = new ArrayList<>();
|
||||||
|
List<String> delIds = new ArrayList<>();
|
||||||
|
Map<String, MsTestElement> updateMap = new HashMap<>();
|
||||||
|
if (CollectionUtils.isNotEmpty(sources)) {
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
MsTestElement msTestElement = sources.get(i);
|
||||||
|
if (StringUtils.isNotEmpty(msTestElement.getId())) {
|
||||||
|
updateMap.put(msTestElement.getId(), msTestElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 找出待更新内容和源已经被删除的内容
|
||||||
|
if (CollectionUtils.isNotEmpty(targets)) {
|
||||||
|
for (int i = 0; i < targets.size(); i++) {
|
||||||
|
MsTestElement msTestElement = targets.get(i);
|
||||||
|
if (msTestElement == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sourceIds.add(msTestElement.getId());
|
||||||
|
if (!StringUtils.equals(msTestElement.getLabel(), SCENARIO_REF)
|
||||||
|
&& StringUtils.isNotEmpty(msTestElement.getId())) {
|
||||||
|
if (updateMap.containsKey(msTestElement.getId())) {
|
||||||
|
targets.set(i, updateMap.get(msTestElement.getId()));
|
||||||
|
updateMap.remove(msTestElement.getId());
|
||||||
|
} else {
|
||||||
|
delIds.add(msTestElement.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除多余的步骤 delIds中包含的全都干掉
|
||||||
|
targets.removeIf(msTestElement -> delIds.contains(msTestElement.getId()));
|
||||||
|
|
||||||
|
// 补充新增的源引用步骤
|
||||||
|
if (CollectionUtils.isNotEmpty(sources)) {
|
||||||
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
|
MsTestElement msTestElement = sources.get(i);
|
||||||
|
if (!sourceIds.contains(msTestElement.getId())) {
|
||||||
|
targets.add(msTestElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
//根据index排序
|
||||||
|
targets.sort(Comparator.comparing(MsTestElement::getIndex));
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<JSONObject> mergeHashTree(List<JSONObject> targets, List<JSONObject> sources) {
|
||||||
try {
|
try {
|
||||||
List<String> sourceIds = new ArrayList<>();
|
List<String> sourceIds = new ArrayList<>();
|
||||||
List<String> delIds = new ArrayList<>();
|
List<String> delIds = new ArrayList<>();
|
||||||
Map<String, JSONObject> updateMap = new HashMap<>();
|
Map<String, JSONObject> updateMap = new HashMap<>();
|
||||||
if (CollectionUtils.isNotEmpty(targets)) {
|
if (CollectionUtils.isNotEmpty(sources)) {
|
||||||
for (int i = 0; i < targets.size(); i++) {
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
JSONObject item = targets.get(i);
|
JSONObject item = sources.get(i);
|
||||||
item.put(MsHashTreeConstants.DISABLED, true);
|
item.put(MsHashTreeConstants.DISABLED, true);
|
||||||
item.put(ElementConstants.REF_ENABLE, true);
|
item.put(ElementConstants.REF_ENABLE, true);
|
||||||
if (StringUtils.isNotEmpty(item.optString(ElementConstants.ID))) {
|
if (StringUtils.isNotEmpty(item.optString(ElementConstants.ID))) {
|
||||||
|
@ -496,9 +569,9 @@ public class ElementUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 找出待更新内容和源已经被删除的内容
|
// 找出待更新内容和源已经被删除的内容
|
||||||
if (CollectionUtils.isNotEmpty(sources)) {
|
if (CollectionUtils.isNotEmpty(targets)) {
|
||||||
for (int i = 0; i < sources.size(); i++) {
|
for (int i = 0; i < targets.size(); i++) {
|
||||||
JSONObject object = sources.get(i);
|
JSONObject object = targets.get(i);
|
||||||
if (object == null) {
|
if (object == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -506,7 +579,7 @@ public class ElementUtil {
|
||||||
if (!StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
if (!StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
||||||
&& StringUtils.isNotEmpty(object.optString(ElementConstants.ID))) {
|
&& StringUtils.isNotEmpty(object.optString(ElementConstants.ID))) {
|
||||||
if (updateMap.containsKey(object.optString(ElementConstants.ID))) {
|
if (updateMap.containsKey(object.optString(ElementConstants.ID))) {
|
||||||
sources.set(i, updateMap.get(object.optString(ElementConstants.ID)));
|
targets.set(i, updateMap.get(object.optString(ElementConstants.ID)));
|
||||||
updateMap.remove(object.optString(ElementConstants.ID));
|
updateMap.remove(object.optString(ElementConstants.ID));
|
||||||
} else {
|
} else {
|
||||||
delIds.add(object.optString(ElementConstants.ID));
|
delIds.add(object.optString(ElementConstants.ID));
|
||||||
|
@ -515,33 +588,29 @@ public class ElementUtil {
|
||||||
// 历史数据兼容
|
// 历史数据兼容
|
||||||
if (!object.has(ElementConstants.ID)
|
if (!object.has(ElementConstants.ID)
|
||||||
&& !StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
&& !StringUtils.equals(object.optString("label"), SCENARIO_REF)
|
||||||
&& i < targets.size()) {
|
&& i < sources.size()) {
|
||||||
sources.set(i, targets.get(i));
|
targets.set(i, sources.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除多余的步骤
|
// 删除多余的步骤
|
||||||
for (int i = 0; i < sources.size(); i++) {
|
targets.removeIf(msTestElement -> delIds.contains(msTestElement.optString(ElementConstants.ID)));
|
||||||
JSONObject source = sources.get(i);
|
|
||||||
if (delIds.contains(source.optString(ElementConstants.ID))) {
|
|
||||||
sources.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 补充新增的源引用步骤
|
// 补充新增的源引用步骤
|
||||||
if (CollectionUtils.isNotEmpty(targets)) {
|
if (CollectionUtils.isNotEmpty(sources)) {
|
||||||
for (int i = 0; i < targets.size(); i++) {
|
for (int i = 0; i < sources.size(); i++) {
|
||||||
JSONObject item = sources.get(i);
|
JSONObject item = sources.get(i);
|
||||||
if (!sourceIds.contains(item.optString(ElementConstants.ID))) {
|
if (!sourceIds.contains(item.optString(ElementConstants.ID))) {
|
||||||
sources.add(item);
|
targets.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return targets;
|
|
||||||
}
|
|
||||||
return sources;
|
return sources;
|
||||||
}
|
}
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getResourceId(String resourceId, ParameterConfig config, MsTestElement parent, String indexPath) {
|
public static String getResourceId(String resourceId, ParameterConfig config, MsTestElement parent, String indexPath) {
|
||||||
if (StringUtils.isNotEmpty(config.getScenarioId()) && StringUtils.equals(config.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
if (StringUtils.isNotEmpty(config.getScenarioId()) && StringUtils.equals(config.getReportType(), RunModeConstants.SET_REPORT.toString())) {
|
||||||
|
@ -748,7 +817,7 @@ public class ElementUtil {
|
||||||
.filter(ScenarioVariable::isConstantValid).forEach(keyValue ->
|
.filter(ScenarioVariable::isConstantValid).forEach(keyValue ->
|
||||||
arguments.addArgument(keyValue.getName(),
|
arguments.addArgument(keyValue.getName(),
|
||||||
StringUtils.isNotBlank(keyValue.getValue())
|
StringUtils.isNotBlank(keyValue.getValue())
|
||||||
? keyValue.getValue().replaceAll("[\r\n]","") : keyValue.getValue(), "="));
|
? keyValue.getValue().replaceAll("[\r\n]", "") : keyValue.getValue(), "="));
|
||||||
List<ScenarioVariable> variableList = variables.stream()
|
List<ScenarioVariable> variableList = variables.stream()
|
||||||
.filter(ScenarioVariable::isListValid).collect(Collectors.toList());
|
.filter(ScenarioVariable::isListValid).collect(Collectors.toList());
|
||||||
variableList.forEach(item -> {
|
variableList.forEach(item -> {
|
||||||
|
@ -772,7 +841,7 @@ public class ElementUtil {
|
||||||
keyValue.getValue() != null && keyValue.getValue().startsWith("@")
|
keyValue.getValue() != null && keyValue.getValue().startsWith("@")
|
||||||
? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue())
|
? ScriptEngineUtils.buildFunctionCallString(keyValue.getValue())
|
||||||
: (StringUtils.isNotBlank(keyValue.getValue())
|
: (StringUtils.isNotBlank(keyValue.getValue())
|
||||||
? keyValue.getValue().replaceAll("[\r\n]","")
|
? keyValue.getValue().replaceAll("[\r\n]", "")
|
||||||
: keyValue.getValue()), "="));
|
: keyValue.getValue()), "="));
|
||||||
// List类型的变量
|
// List类型的变量
|
||||||
List<ScenarioVariable> variableList = config.getConfig().get(projectId).getCommonConfig().getVariables().stream()
|
List<ScenarioVariable> variableList = config.getConfig().get(projectId).getCommonConfig().getVariables().stream()
|
||||||
|
@ -1183,13 +1252,14 @@ public class ElementUtil {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<String> getProjectIds(String scenarioDefinition) {
|
public static List<String> getProjectIds(String scenarioDefinition) {
|
||||||
Pattern pattern = Pattern.compile("\"projectId\"\\s*:\\s*\"?([^\"]*)\"?,");
|
Pattern pattern = Pattern.compile("\"projectId\"\\s*:\\s*\"?([^\"]*)\"?,");
|
||||||
Matcher matcher = pattern.matcher(scenarioDefinition);
|
Matcher matcher = pattern.matcher(scenarioDefinition);
|
||||||
List<String> projectIdLists = new ArrayList<>();
|
List<String> projectIdLists = new ArrayList<>();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
if (!projectIdLists.contains(matcher.group(1))){
|
if (!projectIdLists.contains(matcher.group(1))) {
|
||||||
projectIdLists.add(matcher.group(1));
|
projectIdLists.add(matcher.group(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue