Jmeter通过Beanshell实现json-schema-validator

  • jmeter
  • beanshell
  • jmeter 验证json结构
  • jmeter 验证json中的固定值

1. 什么是Json Schema

定义Json的数据结构与类型

http://json-schema.org/

使用的时候需要注意draft的版本号

2. Json Schema示例

JSON示例

{
  "status": false,
  "data": [{
    "type": "A",
    "content": [{
      "value": "AAA",
      "count": 3
    },
      {
        "value": "BBB",
        "count": 4
      },
      {
        "value": "CCC",
        "count": 5
      },
      ]
  }]
}

对应的JSON schema 示例


{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "status": {
      "type": "boolean"
    },
    "data": {
      "type": "array",
      "items": [
        {
          "type": "object",
          "properties": {
            "type": {
              "type": "string"
            },
            "content": {
              "type": "array",
              "items": 
                {
                  "type": "object",
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "value",
                    "count"
                  ]
                }             
            }
          },
          "required": [
            "type",
            "content"
          ]
        }
      ]
    }
  },
  "required": [
    "status",
    "data"
  ]
}
  • $schema 指定JsonSchema指定的版本号
  • "type" 指定这个Json节点的数据类型,如 "object" "array" "string" "integer" "boolean"
  • "properties":当父类型为“array”时,可以使用"properties"定义其子节点的属性
  • "items": 当父类型为“object”时,可以使用"array"定义其子节点的属性
  • "required": 当某个属性必须存在时,可以使用required, 当做Json scheme validate时,如果json中不存在这个属性,则会报错
  • "enum": 当值不在范围内时,验证时会报fail
"properties": {
    "status": {
      "type": "boolean",
     "enum": [false]
    }

3. Json Schema的生成

有些在线工具支持根据Json生成JsonSchema

Draft4
https://www.liquid-technologies.com/online-json-to-schema-converter

特别注意:

可以删除JsonSchem中的重复元素
例如上面的例子中,生成的JsonSchema中含有多个重复的

{
                  "type": "object",
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "value",
                    "count"
                  ]
                }

删除以后,也需要删除"item"后面的 [ ]

删除以后的示例:

"content": {
              "type": "array",
              "items": 
                {
                  "type": "object",
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "value",
                    "count"
                  ]
                }             
            }
Draft 6,7
https://jsonschema.net/#/

4. Java 根据JsonSchema 验证Json

使用的包是json-schema-validator 2.2.6

https://github.com/java-json-tools/json-schema-validator

            com.github.fge
            json-schema-validator
            2.2.6
        

        
            com.google.guava
            guava
            18.0
        

Jmeter 的bean shell 使用java代码必须catch所有异常,不能Throw

verifyJsonSchema 返回"test pass" or "test fail 与错误报告" or "test fail 与Excerption",Jmeter中根据pass fail,输入assert结果

import com.fasterxml.jackson.databind.JsonNode;
import com.github.fge.jackson.JsonLoader;
import com.github.fge.jsonschema.SchemaVersion;
import com.github.fge.jsonschema.core.exceptions.ProcessingException;
import com.github.fge.jsonschema.core.report.ProcessingReport;
import com.github.fge.jsonschema.main.JsonSchema;
import com.github.fge.jsonschema.main.JsonSchemaFactory;
import java.io.IOException;

public class JsonSchemaTool
{
    public String verifyJsonSchema(String schemaFileName,String jsonStr) {

        try{
            String PKGBASE = String.valueOf('/') ;
            JsonNode fstabSchema = JsonLoader.fromResource(PKGBASE + schemaFileName);
            JsonNode good = JsonLoader.fromString(jsonStr);
            JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
            JsonSchema schema = factory.getJsonSchema(fstabSchema);
            ProcessingReport report;
            report = schema.validate(good);
            System.out.println(report);
            StringBuilder sb = new StringBuilder();
            if (report.toString().contains("ListProcessingReport: success")){
                sb.append("test pass");
            }
            if (report.toString().contains("ListProcessingReport: failure")){
                sb.append("test fail") ;
                sb.append("\n") ;
                sb.append(report.toString()) ;
            }
            if(report.toString().contains("level: \"warning\"")){
                sb.append("\n") ;
                sb.append(" with warning!!!");
            }
            return  sb.toString();
        //返回"test pass" or "test fail 与错误报告" or "test fail 与Excerption"
        //Jmeter 的bean shell 使用java代码必须catch所有异常,不能Throw
        }catch (IOException e){
            return  "IOException " + e.getMessage();
        }catch (ProcessingException e){
            return  "ProcessingException" + e.getMessage();
        }
    }

    public static void main( String[]  args)
    {
        String suggest_schema_test_json = "{\n" +
                "\t\"status\": false,\n" +
                "\t\"data\": [{\n" +
                "\t\t\"type\": \"A\",\n" +
                "\t\t\"content\": [{\n" +
                "\t\t\t\"value2\": \"AAA\",\n" +
                "\t\t\t\"count\": \"abc\"\n" +
                "\t\t},\n" +
                "\t\t{\n" +
                "\t\t\t\"value\": \"BBB\",\n" +
                "\t\t\t\"count\": 4\n" +
                "\t\t},\n" +
                "\t\t{\n" +
                "\t\t\t\"value\": \"CCC\",\n" +
                "\t\t\t\"count\": 6\n" +
                "\t\t}\n" +
                "\t\t]\n" +
                "\t}]\n" +
                "}";
        System.out.println(new JsonSchemaTool().verifyJsonSchema("/suggest_schema.json",suggest_schema_test_json));
    }
}

目录结构


Jmeter通过Beanshell实现json-schema-validator_第1张图片
contents.png

运行结果:
例如 缺少一个required的属性,或者 属性的类型错误
输出的验证失败的原因。


test fail
com.github.fge.jsonschema.core.report.ListProcessingReport: failure
--- BEGIN MESSAGES ---
error: object has missing required properties (["value"])
    level: "error"
    schema: {"loadingURI":"#","pointer":"/properties/data/items/0/properties/content/items"}
    instance: {"pointer":"/data/0/content/0"}
    domain: "validation"
    keyword: "required"
    required: ["count","value"]
    missing: ["value"]
---  END MESSAGES  ---
  1. Jmeter中使用BeanShell集成 JsonSchemaTool
  • Jmeter中配置JsonSchema所在的路径


    Jmeter通过Beanshell实现json-schema-validator_第2张图片
    add_directory.png
  • Jmeter中定义java文件所在的路径


    Jmeter通过Beanshell实现json-schema-validator_第3张图片
    tool_path.png
  • BeanShell 结构


    beanshell结构.png
  • BeanShell PreProcessor-getResponse

String response_data = prev.getResponseDataAsString();
vars.put("response_data",response_data);
log.info("-----------response_data------------------"+response_data);
  • BeanShell PostProcessor-generateTestResult
String schemapath = vars.get("schemapath");
source(schemapath);
String response_data  = vars.get("response_data");
try{
    String assertResult = new JsonSchemaTool().verifyJsonSchema("/suggest_schema.json",response_data);
    log.info("-----------assertResult------------------"+assertResult);
    vars.put("assertResult",assertResult);
    
} catch (Throwable ex) {
    log.error("Beanshell failure: ", ex);
    throw ex;
}
  • BeanShell Assert
String assertResult = vars.get("assertResult");
log.info("-----beanshell assert------assertResult------------------"+assertResult);
if(assertResult.contains("test fail")){           
    Failure = true;  
    FailureMessage = assertResult; 
} 
  • Jmeter运行Test
    需要的jar包放置在本地的Jmeter路径下
    D:\TestTools\apache-jmeter-3.1\lib\ext


    Jmeter通过Beanshell实现json-schema-validator_第4张图片
    run_result.png

你可能感兴趣的:(Jmeter通过Beanshell实现json-schema-validator)