fix(接口测试): json-schema自动生成没有按长度截取
--bug=1044063 --user=陈建星 【接口测试】接口-json请求参数-schema格式-跟节点array类型-无子字段-高级设置最大最小元素数量-自动生成数据为空数组 https://www.tapd.cn/55049933/s/1549783
This commit is contained in:
parent
9b6184057f
commit
cfcf184a0d
|
@ -32,8 +32,6 @@ public class JsonSchemaBuilder {
|
|||
}
|
||||
|
||||
private static JsonNode generateJson(JsonNode jsonSchemaNode, Map<String, String> processMap, boolean isPreview) {
|
||||
ObjectNode jsonNode = ApiDataUtils.createObjectNode();
|
||||
|
||||
if (jsonSchemaNode instanceof NullNode) {
|
||||
return NullNode.getInstance();
|
||||
}
|
||||
|
@ -42,6 +40,7 @@ public class JsonSchemaBuilder {
|
|||
JsonNode propertiesNode = jsonSchemaNode.get(PropertyConstant.PROPERTIES);
|
||||
// 遍历 properties
|
||||
if (propertiesNode != null) {
|
||||
ObjectNode jsonNode = ApiDataUtils.createObjectNode();
|
||||
propertiesNode.fields().forEachRemaining(entry -> {
|
||||
String propertyName = entry.getKey();
|
||||
JsonNode propertyNode = entry.getValue();
|
||||
|
@ -51,20 +50,38 @@ public class JsonSchemaBuilder {
|
|||
// 将属性和值添加到 JSON 对象节点
|
||||
jsonNode.set(propertyName, valueNode);
|
||||
});
|
||||
return jsonNode;
|
||||
}
|
||||
} else if (StringUtils.equals(type, PropertyConstant.ARRAY)) {
|
||||
JsonNode items = jsonSchemaNode.get(PropertyConstant.ITEMS);
|
||||
JsonNode maxItems = jsonSchemaNode.get(PropertyConstant.MAX_ITEMS);
|
||||
JsonNode minItems = jsonSchemaNode.get(PropertyConstant.MIN_ITEMS);
|
||||
if (items != null) {
|
||||
ArrayNode arrayNode = new ArrayNode(JsonNodeFactory.instance);
|
||||
items.forEach(item -> {
|
||||
JsonNode valueNode = isPreview ? generateValueForPreview(null, item, processMap)
|
||||
: generateValue(null, item, processMap);
|
||||
arrayNode.add(valueNode);
|
||||
});
|
||||
if (isPreview) {
|
||||
items.forEach(item -> arrayNode.add(generateValueForPreview(null, item, processMap)));
|
||||
} else {
|
||||
int max = isTextNotBlank(maxItems) ? maxItems.asInt() : Integer.MAX_VALUE;
|
||||
int min = isTextNotBlank(minItems) ? minItems.asInt() : 0;
|
||||
// 自动生成数据,根据 minItems 和 maxItems 生成
|
||||
int itemSize = Math.min(items.size(), max);
|
||||
for (int i = 0; i < itemSize; i++) {
|
||||
JsonNode itemNode = items.get(i);
|
||||
JsonNode valueNode = generateValue(null, itemNode, processMap);
|
||||
arrayNode.add(valueNode);
|
||||
}
|
||||
if (min > itemSize) {
|
||||
for (int i = itemSize; i < min; i++) {
|
||||
// 如果不足最小个数,则默认补充字符类型的数组项
|
||||
TextNode itemNode = new TextNode(generateStr(8));
|
||||
arrayNode.add(itemNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arrayNode;
|
||||
}
|
||||
}
|
||||
return jsonNode;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static JsonNode generateValueForPreview(String propertyName, JsonNode propertyNode, Map<String, String> processMap) {
|
||||
|
@ -75,8 +92,7 @@ public class JsonSchemaBuilder {
|
|||
String type = getPropertyTextValue(propertyNode, PropertyConstant.TYPE);
|
||||
String value = getPropertyTextValue(propertyNode, PropertyConstant.EXAMPLE);
|
||||
return switch (type) {
|
||||
case PropertyConstant.STRING ->
|
||||
new TextNode(StringUtils.isBlank(value) ? "string" : value);
|
||||
case PropertyConstant.STRING -> new TextNode(StringUtils.isBlank(value) ? "string" : value);
|
||||
case PropertyConstant.INTEGER -> {
|
||||
if (isVariable(value)) {
|
||||
yield getJsonNodes(propertyName, processMap, value);
|
||||
|
@ -103,14 +119,7 @@ public class JsonSchemaBuilder {
|
|||
}
|
||||
}
|
||||
case PropertyConstant.OBJECT -> generateJson(propertyNode, processMap, true);
|
||||
case PropertyConstant.ARRAY -> {
|
||||
ArrayNode arrayNode = new ArrayNode(JsonNodeFactory.instance);
|
||||
JsonNode items = propertyNode.get(PropertyConstant.ITEMS);
|
||||
if (items != null) {
|
||||
items.forEach(item -> arrayNode.add(generateValueForPreview(null, item, processMap)));
|
||||
}
|
||||
yield arrayNode;
|
||||
}
|
||||
case PropertyConstant.ARRAY -> generateJson(propertyNode, processMap, true);
|
||||
default -> NullNode.getInstance();
|
||||
};
|
||||
|
||||
|
@ -135,13 +144,22 @@ public class JsonSchemaBuilder {
|
|||
int min = isTextNotBlank(minLength) ? minLength.asInt() : 1;
|
||||
if (enumValues != null && enumValues instanceof ArrayNode) {
|
||||
value = enumValues.get(new Random().nextInt(enumValues.size())).asText();
|
||||
} else if (isTextNotBlank(defaultValue)) {
|
||||
value = defaultValue.asText();
|
||||
if (value.length() > max) {
|
||||
value = value.substring(0, max);
|
||||
}
|
||||
} else if (isTextNotBlank(pattern)) {
|
||||
Xeger generator = new Xeger(pattern.asText());
|
||||
value = generator.generate();
|
||||
} else if (isTextNotBlank(defaultValue)) {
|
||||
value = defaultValue.asText();
|
||||
if (value.length() > max) {
|
||||
value = value.substring(0, max);
|
||||
}
|
||||
if (value.length() < min) {
|
||||
value = value + generateStr(min - value.length());
|
||||
}
|
||||
} else {
|
||||
value = RandomStringGenerator.builder().withinRange('0', 'z').build().generate(new Random().nextInt(max - min + 1) + min);
|
||||
value = generateStr(new Random().nextInt(max - min + 1) + min);
|
||||
}
|
||||
}
|
||||
yield new TextNode(value);
|
||||
|
@ -207,20 +225,17 @@ public class JsonSchemaBuilder {
|
|||
yield BooleanNode.valueOf(propertyNode.get(PropertyConstant.EXAMPLE).asBoolean());
|
||||
}
|
||||
}
|
||||
case PropertyConstant.OBJECT -> generateJson(propertyNode, processMap, true);
|
||||
case PropertyConstant.ARRAY -> {
|
||||
ArrayNode arrayNode = new ArrayNode(JsonNodeFactory.instance);
|
||||
JsonNode items = propertyNode.get(PropertyConstant.ITEMS);
|
||||
if (items != null) {
|
||||
items.forEach(item -> arrayNode.add(generateValue(null, item, processMap)));
|
||||
}
|
||||
yield arrayNode;
|
||||
}
|
||||
case PropertyConstant.OBJECT -> generateJson(propertyNode, processMap, false);
|
||||
case PropertyConstant.ARRAY -> generateJson(propertyNode, processMap, false);
|
||||
default -> NullNode.getInstance();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private static String generateStr(int length) {
|
||||
return RandomStringGenerator.builder().withinRange('0', 'z').build().generate(length);
|
||||
}
|
||||
|
||||
private static boolean isTextNotBlank(JsonNode jsonNode) {
|
||||
return jsonNode != null && !(jsonNode instanceof NullNode) && StringUtils.isNotBlank(jsonNode.asText());
|
||||
}
|
||||
|
|
|
@ -1801,6 +1801,12 @@ public class ApiDefinitionControllerTests extends BaseTest {
|
|||
{"id":null,"title":null,"example":null,"type":"object","description":null,"items":null,"properties":{"array":{"id":null,"title":null,"example":null,"type":"array","description":null,"items":[{"id":null,"title":null,"example":"","type":"string","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":"默认值","pattern":null,"maxLength":4,"minLength":0,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},{"id":null,"title":null,"example":"","type":"number","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true}],"properties":null,"additionalProperties":null,"required":null,"defaultValue":null,"pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},"string":{"id":null,"title":null,"example":"","type":"string","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":"","pattern":"[A-Z0-9_]+","maxLength":5,"minLength":1,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},"int":{"id":null,"title":null,"example":"","type":"integer","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":3,"pattern":null,"maxLength":null,"minLength":null,"minimum":0,"maximum":4,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},"num":{"id":null,"title":null,"example":"","type":"number","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":2,"pattern":null,"maxLength":null,"minLength":null,"minimum":0,"maximum":5,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},"boolean":{"id":null,"title":null,"example":"","type":"boolean","description":"","items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":"true","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true},"null":{"id":null,"title":null,"example":null,"type":"null","description":null,"items":null,"properties":null,"additionalProperties":null,"required":null,"defaultValue":null,"pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true}},"additionalProperties":null,"required":null,"defaultValue":null,"pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enumValues":null,"enable":true}
|
||||
""";
|
||||
requestPostWithOk(JSON_SCHEMA_AUTO_GENERATE, JSON.parseObject(jsonString, JsonSchemaItem.class));
|
||||
|
||||
// 长度截取
|
||||
jsonString = """
|
||||
{"type":"object","enable":true,"properties":{"arraywww":{"type":"array","enable":true,"items":[{"type":"string","example":"1","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true},{"type":"number","example":"2","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true}],"minItems":null,"maxItems":null},"string":{"type":"string","example":"@natural(1,100)","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true},"int":{"type":"integer","example":"intValue","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true},"num":{"type":"number","example":"","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true},"boolean":{"type":"boolean","example":"booleanValue","description":"","additionalProperties":null,"defaultValue":"","pattern":null,"maxLength":null,"minLength":null,"minimum":null,"maximum":null,"maxItems":null,"minItems":null,"format":null,"enable":true},"null":{"type":"null","enable":true},"默认值大于最大长度":{"type":"string","example":"","description":"","enable":true,"defaultValue":"sdfdsd","maxLength":1,"minLength":0},"默认值小于最小长度":{"type":"string","example":"","description":"","enable":true,"defaultValue":"1","maxLength":3,"minLength":2},"数组项小于最小项":{"type":"array","enable":true,"items":[],"minItems":2,"maxItems":3},"数组项大于最大项":{"type":"array","enable":true,"items":[null,null],"minItems":0,"maxItems":1},"正则大于最大长度":{"type":"string","example":"","description":"","enable":true,"defaultValue":"","maxLength":2,"minLength":0,"pattern":"[A-Z]{4}"}}}
|
||||
""";
|
||||
requestPostWithOk(JSON_SCHEMA_AUTO_GENERATE, JSON.parseObject(jsonString, JsonSchemaItem.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -29,5 +29,7 @@ public class PropertyConstant {
|
|||
public final static String MIN_LENGTH = "minLength";
|
||||
public final static String MINIMUM = "minimum";
|
||||
public final static String MAXIMUM = "maximum";
|
||||
public final static String MAX_ITEMS = "maxItems";
|
||||
public final static String MIN_ITEMS = "minItems";
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue