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) { private void addAssertions(HashTree hashTree) {
// 增加JSON文档结构校验 // 增加JSON文档结构校验
if (this.getDocument() != null && this.getDocument().getType().equals("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); ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
this.getDocument().getData().setJson(apiDefinitionService.getDocument(this.getDocument().getData().getJsonFollowAPI(), "JSON")); this.getDocument().getData().setJson(apiDefinitionService.getDocument(this.getDocument().getData().getJsonFollowAPI(), "JSON"));
} }
@ -55,7 +55,7 @@ public class MsAssertions extends MsTestElement {
} }
// 增加XML文档结构校验 // 增加XML文档结构校验
if (this.getDocument() != null && this.getDocument().getType().equals("XML") && CollectionUtils.isNotEmpty(this.getDocument().getData().getXml())) { 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); ApiDefinitionService apiDefinitionService = CommonBeanFactory.getBean(ApiDefinitionService.class);
this.getDocument().getData().setXml(apiDefinitionService.getDocument(this.getDocument().getData().getXmlFollowAPI(), "XML")); 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); isTrue = getLength(subj, decimalFormatter) != getLength(item.getValue(), decimalFormatter);
break; break;
case "length_gt": case "length_gt":
isTrue = getLength(subj, decimalFormatter) > getLength(item.getValue(), decimalFormatter); isTrue = getLength(subj, decimalFormatter) < getLength(item.getValue(), decimalFormatter);
break; break;
case "length_lt": case "length_lt":
isTrue = getLength(subj, decimalFormatter) < getLength(item.getValue(), decimalFormatter); isTrue = getLength(subj, decimalFormatter) > getLength(item.getValue(), decimalFormatter);
break; break;
case "regular": case "regular":
Pattern pattern = JMeterUtils.getPatternCache().getPattern(expectedValue); 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.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.json.XML;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
public class JSONToDocumentUtils { public class JSONToDocumentUtils {
@ -27,10 +29,20 @@ public class JSONToDocumentUtils {
jsonDataFormatting((JSONObject) value, childrenElements); jsonDataFormatting((JSONObject) value, childrenElements);
} else if (value instanceof JSONArray) { } else if (value instanceof JSONArray) {
List<DocumentElement> childrenElements = new LinkedList<>(); 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); jsonDataFormatting((JSONArray) value, childrenElements);
} else { } 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); jsonDataFormatting((JSONObject) value, childrenElements);
} else if (value instanceof JSONArray) { } else if (value instanceof JSONArray) {
List<DocumentElement> childrenElements = new LinkedList<>(); 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); jsonDataFormatting((JSONArray) value, childrenElements);
} else { } 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) { public static List<DocumentElement> getDocument(String json, String type) {
try { try {
if (StringUtils.equals(type, "JSON")) { if (StringUtils.equals(type, "JSON")) {
List<DocumentElement> roots = new LinkedList<>(); return getJsonDocument(json, type);
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;
} else if (StringUtils.equals(type, "XML")) { } 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 { } else {
return new LinkedList<DocumentElement>() {{ return new LinkedList<DocumentElement>() {{
this.add(new DocumentElement().newRoot("object", null)); 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(); List<Element> listElement = node.elements();
if (listElement.isEmpty()) { 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) {//遍历所有一级子节点 for (Element element : listElement) {//遍历所有一级子节点
List<Element> elementNodes = element.elements(); 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-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>
<el-tooltip effect="dark" content="添加子字段" placement="top-start"> <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>
<el-tooltip effect="dark" :content="$t('commons.remove')" placement="top-start"> <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> </el-tooltip>
</span> </span>
</template> </template>
@ -133,18 +133,18 @@ export default {
}, },
created() { created() {
if (this.document.type === "JSON") { 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") { } 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(); this.changeData();
}, },
watch: { watch: {
'document.type'() { 'document.type'() {
if (this.document.type === "JSON") { 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") { } 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(); this.changeData();
} }
@ -162,6 +162,8 @@ export default {
} }
}, },
checkedAPI() { checkedAPI() {
this.document.data.jsonFollowAPI = "";
this.document.data.xmlFollowAPI = "";
this.changeData(); this.changeData();
}, },
reload() { reload() {