美文网首页接口自动化助手
Jmeter通过Beanshell实现json-schema-v

Jmeter通过Beanshell实现json-schema-v

作者: alexbai326 | 来源:发表于2018-04-19 18:20 被阅读0次
    • 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
    
    <dependency>
                <groupId>com.github.fge</groupId>
                <artifactId>json-schema-validator</artifactId>
                <version>2.2.6</version>
            </dependency>
    
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>18.0</version>
            </dependency>
    

    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));
        }
    }
    
    

    目录结构


    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所在的路径


      add_directory.png
    • Jmeter中定义java文件所在的路径


      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


      run_result.png

    相关文章

      网友评论

        本文标题:Jmeter通过Beanshell实现json-schema-v

        本文链接:https://www.haomeiwen.com/subject/lpzwkftx.html