fix(接口测试): 修复xml断言解析和执行问题

--bug=1008058 --user=赵勇 【接口定义】-接口定义-TEST-添加的xml文档结构断言后添加多个校验断言结果匹配错误 https://www.tapd.cn/55049933/s/1069958
fix: 遗憾缺陷issue 统计 用户组权限
This commit is contained in:
fit2-zhao 2021-11-18 17:09:05 +08:00 committed by fit2-zhao
parent 7bf7db89fc
commit c3ad2c1c9d
4 changed files with 86 additions and 29 deletions

View File

@ -45,7 +45,7 @@ public class MsAssertions extends MsTestElement {
private void addAssertions(HashTree hashTree) {
// 增加JSON文档结构校验
if (this.getDocument() != null && this.getDocument().getType().equals("JSON")) {
if (StringUtils.isNotEmpty(this.getDocument().getData().getJsonFollowAPI())) {
if (StringUtils.isNotEmpty(this.getDocument().getData().getJsonFollowAPI()) && !this.getDocument().getData().getJsonFollowAPI().equals("false")) {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
this.getDocument().getData().setJson(apiDefinitionService.getDocument(this.getDocument().getData().getJsonFollowAPI(), "JSON"));
}
@ -55,7 +55,7 @@ public class MsAssertions extends MsTestElement {
}
// 增加XML文档结构校验
if (this.getDocument() != null && this.getDocument().getType().equals("XML") && CollectionUtils.isNotEmpty(this.getDocument().getData().getXml())) {
if (StringUtils.isNotEmpty(this.getDocument().getData().getXmlFollowAPI())) {
if (StringUtils.isNotEmpty(this.getDocument().getData().getXmlFollowAPI()) && !this.getDocument().getData().getXmlFollowAPI().equals("false")) {
ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
this.getDocument().getData().setXml(apiDefinitionService.getDocument(this.getDocument().getData().getXmlFollowAPI(), "XML"));
}

View File

@ -38,10 +38,10 @@ public class DocumentUtils {
isTrue = getLength(subj, decimalFormatter) != getLength(item.getValue(), decimalFormatter);
break;
case "length_gt":
isTrue = getLength(subj, decimalFormatter) > getLength(item.getValue(), decimalFormatter);
isTrue = getLength(subj, decimalFormatter) < getLength(item.getValue(), decimalFormatter);
break;
case "length_lt":
isTrue = getLength(subj, decimalFormatter) < getLength(item.getValue(), decimalFormatter);
isTrue = getLength(subj, decimalFormatter) > getLength(item.getValue(), decimalFormatter);
break;
case "regular":
Pattern pattern = JMeterUtils.getPatternCache().getPattern(expectedValue);

View File

@ -10,11 +10,13 @@ import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.json.XML;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
public class JSONToDocumentUtils {
@ -27,10 +29,20 @@ public class JSONToDocumentUtils {
jsonDataFormatting((JSONObject) value, childrenElements);
} else if (value instanceof JSONArray) {
List<DocumentElement> childrenElements = new LinkedList<>();
children.add(new DocumentElement("", "array", "", childrenElements));
DocumentElement documentElement = new DocumentElement("", "array", "", childrenElements);
documentElement.setArrayVerification(true);
children.add(documentElement);
jsonDataFormatting((JSONArray) value, childrenElements);
} else {
children.add(new DocumentElement("", "string", value, null));
String type = "string";
if (value != null) {
if (isWholeNumber(value.toString())) {
type = "integer";
} else if (isNumber(value.toString())) {
type = "number";
}
}
children.add(new DocumentElement("", type, value, null));
}
}
}
@ -44,33 +56,58 @@ public class JSONToDocumentUtils {
jsonDataFormatting((JSONObject) value, childrenElements);
} else if (value instanceof JSONArray) {
List<DocumentElement> childrenElements = new LinkedList<>();
children.add(new DocumentElement(key, "array", "", childrenElements));
DocumentElement documentElement = new DocumentElement(key, "array", "", childrenElements);
documentElement.setArrayVerification(true);
children.add(documentElement);
jsonDataFormatting((JSONArray) value, childrenElements);
} else {
children.add(new DocumentElement(key, "string", value, null));
String type = "string";
if (value != null) {
if (isWholeNumber(value.toString())) {
type = "integer";
} else if (isNumber(value.toString())) {
type = "number";
}
}
children.add(new DocumentElement(key, type, value, null));
}
}
}
private static List<DocumentElement> getJsonDocument(String json, String type) {
List<DocumentElement> roots = new LinkedList<>();
List<DocumentElement> children = new LinkedList<>();
Object typeObject = new JSONTokener(json).nextValue();
if (typeObject instanceof net.sf.json.JSONArray) {
if (StringUtils.equals(type, "JSON")) {
roots.add(new DocumentElement().newRoot("array", children));
JSONArray array = JSON.parseArray(json);
jsonDataFormatting(array, children);
} else {
JSONArray array = JSON.parseArray(json);
jsonDataFormatting(array, roots);
}
} else {
if (StringUtils.equals(type, "JSON")) {
roots.add(new DocumentElement().newRoot("object", children));
JSONObject object = JSON.parseObject(json);
jsonDataFormatting(object, children);
} else {
JSONObject object = JSON.parseObject(json);
jsonDataFormatting(object, roots);
}
}
return roots;
}
public static List<DocumentElement> getDocument(String json, String type) {
try {
if (StringUtils.equals(type, "JSON")) {
List<DocumentElement> roots = new LinkedList<>();
List<DocumentElement> children = new LinkedList<>();
Object typeObject = new JSONTokener(json).nextValue();
if (typeObject instanceof net.sf.json.JSONArray) {
roots.add(new DocumentElement().newRoot("array", children));
JSONArray array = JSON.parseArray(json);
jsonDataFormatting(array, children);
} else {
roots.add(new DocumentElement().newRoot("object", children));
JSONObject object = JSON.parseObject(json);
jsonDataFormatting(object, children);
}
return roots;
return getJsonDocument(json, type);
} else if (StringUtils.equals(type, "XML")) {
return getXmlDocument(json);
org.json.JSONObject xmlJSONObj = XML.toJSONObject(json);
String jsonPrettyPrintString = xmlJSONObj.toString(4);
return getJsonDocument(jsonPrettyPrintString, type);
} else {
return new LinkedList<DocumentElement>() {{
this.add(new DocumentElement().newRoot("object", null));
@ -82,6 +119,16 @@ public class JSONToDocumentUtils {
}
}
public static boolean isNumber(String number) {
Pattern pattern = Pattern.compile("^-?\\d+(\\.\\d+)?$");
return StringUtils.isNotEmpty(number) && pattern.matcher(number).matches();
}
public static boolean isWholeNumber(String wholeNumber) {
Pattern pattern = Pattern.compile("[+-]?[0-9]+?");
return StringUtils.isNotEmpty(wholeNumber) && pattern.matcher(wholeNumber).matches();
}
/**
* 从指定节点开始,递归遍历所有子节点
@ -90,7 +137,15 @@ public class JSONToDocumentUtils {
//递归遍历当前节点所有的子节点
List<Element> listElement = node.elements();
if (listElement.isEmpty()) {
children.add(new DocumentElement(node.getName(), "string", node.getTextTrim(), null));
String type = "string";
if (StringUtils.isNotEmpty(node.getTextTrim())) {
if (isWholeNumber(node.getText())) {
type = "integer";
} else if (isNumber(node.getText())) {
type = "number";
}
}
children.add(new DocumentElement(node.getName(), type, node.getTextTrim(), null));
}
for (Element element : listElement) {//遍历所有一级子节点
List<Element> elementNodes = element.elements();

View File

@ -74,10 +74,10 @@
<el-button icon="el-icon-document-checked" circle type="primary" size="mini" @click="addVerification(scope.row)" :disabled="scope.row.type ==='object' ||scope.row.type ==='array' || checked || scope.row.id==='root'"/>
</el-tooltip>
<el-tooltip effect="dark" content="添加子字段" placement="top-start">
<el-button icon="el-icon-plus" circle type="primary" size="mini" style="margin-left: 10px" @click="addRow(scope.row)" :disabled="(scope.row.type !=='object' && scope.row.type !=='array') || checked"/>
<el-button icon="el-icon-plus" circle type="primary" size="mini" style="margin-left: 10px" @click="addRow(scope.row)" :disabled="(scope.row.type !=='object' && scope.row.type !=='array') || checked"/>
</el-tooltip>
<el-tooltip effect="dark" :content="$t('commons.remove')" placement="top-start">
<el-button icon="el-icon-delete" type="primary" circle size="mini" style="margin-left: 10px" @click="remove(scope.row)" :disabled="checked || scope.row.id==='root'"/>
<el-button icon="el-icon-delete" type="primary" circle size="mini" style="margin-left: 10px" @click="remove(scope.row)" :disabled="checked || scope.row.id==='root'"/>
</el-tooltip>
</span>
</template>
@ -133,18 +133,18 @@ export default {
},
created() {
if (this.document.type === "JSON") {
this.checked = this.document.data.jsonFollowAPI ? true : false;
this.checked = this.document.data.jsonFollowAPI && this.document.data.jsonFollowAPI !== "false" ? true : false;
} else if (this.document.type === "XML") {
this.checked = this.document.data.xmlFollowAPI ? true : false;
this.checked = this.document.data.xmlFollowAPI && this.document.data.xmlFollowAPI !== "false" ? true : false;
}
this.changeData();
},
watch: {
'document.type'() {
if (this.document.type === "JSON") {
this.checked = this.document.data.jsonFollowAPI ? true : false;
this.checked = this.document.data.jsonFollowAPI && this.document.data.jsonFollowAPI !== "false" ? true : false;
} else if (this.document.type === "XML") {
this.checked = this.document.data.xmlFollowAPI ? true : false;
this.checked = this.document.data.xmlFollowAPI && this.document.data.xmlFollowAPI !== "false" ? true : false;
}
this.changeData();
}
@ -162,6 +162,8 @@ export default {
}
},
checkedAPI() {
this.document.data.jsonFollowAPI = "";
this.document.data.xmlFollowAPI = "";
this.changeData();
},
reload() {