• Jmeter-BeanShell断言的运用一(JSON响应数据与数据库比对)


    前言

      最近在学习BeanShell断言,发现有点强大哈,只要会写代码,就没有什么是断言不了的,哈哈哈,不过我现在只会写点蹩脚的代码,下面将介绍下如何将返回的JSON数据与数据库数据做对比。

    注:本次涉及到的知识点有 1)BeanShell PostProcessor拼接字符串;2)BeanShell 断言的基本使用;

    背景

      jmeter断言接口返回的count与数据库查询出来的是否一致,接口返回的JSON响应数据如下:

      (count说明:比如12/17,即12是代表商品数 [先用X代替],17是代表收藏夹的数量 [用Y代替])XY只是为了方便区分,后面方便偷懒,哈哈。

    {
        "code":"0",
        "msg":"OK",
        "info":{
            "categoryList":[
                {
                    "id":45,
                    "categoryName":"ca文件夹",
                    "imageUrlList":[
                        "https://img/29/15302571783635805807.jpg"
                    ],
                    "count":2,
                    "tip":null
                }
            ],
            "count":"12/17"
        }
    }

    思路

      第一步:用sql分别查出商品数和收藏夹数,然后拼接成“12/17”的形式;

      第二步:提取出响应数据的count值;(这一步其实有很多种实现方法,比如用jsonpath也可以提取,但本次用的是BeanShell取值哈)

      第三步:将提取出的count与数据库查询说来的拼接值做对比,判断是否一致。

    一、BeanShell知识点摘要(*必看

      如果之前没有接触过BeanShell的话,这节一点要仔细看哈,虽然只是简单提及几个知识点。

    1、什么是Bean Shell

    • BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;
    • BeanShell是一种松散类型的脚本语言(这点和JS类似);
    • BeanShell是用Java写成的,一个小型的、免费的、可以下载的、嵌入式的Java源代码解释器,具有对象脚本语言特性,非常精简的解释器jar文件大小为175k。
    • BeanShell执行标准Java语句和表达式,另外包括一些脚本命令和语法。
    • BeanShell断言中可以通过ResponseCode、ResponseHeaders及pre.getResponseDataAsString()来分别获得String格式的响应状态码、响应头、响应体数据,结合if判断通过变量Failure=false或Failure=true来设置断言是否通过,当设置Failure=true时,还可以设置FailureMessage来设置失败原因

    2、Bean Shell常用内置变量

        JMeter在它的BeanShell中内置了变量,用户可以通过这些变量与JMeter进行交互,其中主要的变量及其使用方法如下:

    • log:写入信息到jmeber.log文件,使用方法:log.info(“This is log info!”);

    • ctx:该变量引用了当前线程的上下文,使用方法可参考:org.apache.jmeter.threads.JMeterContext

    • vars - (JMeterVariables):操作jmeter变量,这个变量实际引用了JMeter线程中的局部变量容器(本质上是Map),它是测试用例与BeanShell交互的桥梁,常用方法:

        a) vars.get(String key):从jmeter中获得变量值

        b) vars.put(String key,String value):数据存到jmeter变量中

        更多方法可参考:org.apache.jmeter.threads.JMeterVariables

    • props - (JMeterProperties - class java.util.Properties):操作jmeter属性,该变量引用了JMeter的配置信息,可以获取Jmeter的属性,它的使用方法与vars类似,但是只能put进去String类型的值,而不能是一个对象。对应于java.util.Properties。 

        a) props.get("START.HMS");  注:START.HMS为属性名,在文件jmeter.properties中定义 

        b) props.put("PROP1","1234"); 

    • prev - (SampleResult):获取前面的sample返回的信息,常用方法:

        a) getResponseDataAsString():获取响应信息

        b) getResponseCode() :获取响应code

        更多方法可参考:org.apache.jmeter.samplers.SampleResult

    • sampler - (Sampler):gives access to the current sampler

    3、Bean Shell判断返回的JSON

      首先要下载JSON依赖包(org.json.jar),放到apache-jmeter-5.0libext中,然后重启jmeter即可在beanshell中import json包了。具体要怎么提取到JSON中的某个值,在博文最后会贴代码,请拉到最后查看,后续也会根据不同的JSON结构专门写一篇如何提取JSON结构字段值的文章。

    4、JSONObject对象除了getString()方法外,还支持

    • getBoolean("字段名") :获取布尔类型字段值
    • getInt("字段名"):获取整型字段值
    • getLong("字段名"):获取长整型字段值
    • getDouble("字段名"):获取双精型字段值
    • getJSONObject("字段名"):获取嵌套Object类型字段值,JSONObject类型
    • getJSONArray("字段名"):获取嵌套Array类型,JSONArray类型

    5、简单断言举例

    状态码断言

    //状态码断言
    log.info("状态码:" + ResponseCode);
    if(ResponseCode.equals("200")){ 
        Failure=false;
    }
    else{
        Failure=true;
        FailureMessage="响应状态码非200";  //指定失败原因
    }

    注:字符串只能使用双引号,字符串相等要使用"".equals("")

    响应体包含特定字符

    //获取响应数据
    String response = prev.getResponseDataAsString();
    log.info("响应体:" + response);
    //响应数据包含
    if(response.contains("登录成功")){
        Failure=false;
    }
    else{
        Failure=true;
        FailureMessage="响应数据不包含登录成功";
    }

    二、实例操作第一步:sql查询

      jmeter连接数据库在之前就已经讲过了,这里就不再赘述了哈,直接进入主题了。这次的查询比较特别一点,为什么呢?因为查询用到的表在不同的数据库中,不是同一个库了,为了方便理解,还是大概说一下吧。

    category表在A库,collect表在B库,在查collect表里的商品数时,是需要用到category表查询出来的id的,因为查询出来的id可能不止一个,所以就会涉及到要将id拼接成一个list的字符串,例如:ids = 1606973,1606974,1606975

    最后将其作为参数,再放到collect表里查询。说的可能比较抽象,哈哈哈,下面直接上图了。

    1、查询category表的文件夹总数,即count中的X

      添加JDBC Request,具体写法如下:

    2、查询category表的文件夹的id(用在另一个库的数据表的)

      添加JDBC Request,具体写法如下:

    3、将category表查询出的文件夹的id拼接起来

      添加BeanShell PostProcessor,编写简单的Java代码,循环所有的id,拼装成list字符串,并保存到参数中,供后续sql查询时调用,Script写法如下:

    //先取得id的数量,即查询出来一共有多少个id,这里可以直接引用A_#,可以看debug sampler
    log.info("ids的数量为:"+vars.get("A_#"));
    int id = Integer.valueOf("${A_#}");
    
    //定义变量ids,用来存放拼接后的字符串
    String ids = "";
    
    //用id数量去for循环,循环查询出每个id,并拼接成字符串
    for(i=1; i<=id; i++){
        String Id = vars.get("A_"+i);
        log.info("Id为:" + vars.get("A_" + i));
        ids += Id + ",";
        }
    
    //去掉字符串最后一个多余的逗号
    ids = ids.substring(0, ids.length() - 1);
    
    log.info("ids为:" + ids);
    
    //将id列表保存为参数
    vars.put("ids",ids);

    4、查询collect表的商品总数,即count中的Y

      添加JDBC Request,具体写法如下:

    三、实例操作第二、三步:提取JSON字段和断言

      添加背景里说到的接口的http请求,在http请求里添加BeanShell断言,Script写法如下:

    //导入json的包
    import org.json.*;
    
    //获取响应结果,并转换为json
    String response = prev.getResponseDataAsString();
    JSONObject responseJson = new JSONObject(response);
    log.info("输出转换为JSON对象的响应数据:" + responseJson);
    
    /*获取categoryList数组的数据:这个与本次断言无关
    JSONArray categoryList = responseJson.getJSONObject("info").getJSONArray("categoryList");
    log.info("categoryList:" + categoryList);
    String message = responseJson.getString("msg");
    log.info("响应message字段:" + message);
    */
    
    //获取count的值
    String count = responseJson.getJSONObject("info").getString("count");
    log.info("请求响应结果返回的count的值为" + count);
    
    //将数据库查询出来的文件夹总数和商品总数拼接起来,比如12/19
    sqlcount=${B_1}+"/"+${C_1};
    log.info("第一种方法直接引用变量去拼接的值为:"+sqlcount);
    
    String sqlcountB = vars.get("B_1");
    String sqlcountC = vars.get("C_1");
    sqlcount2= sqlcountB +"/"+sqlcountC;
    log.info("第二种方法用vars.get到值再拼接的值为:"+sqlcount2);
    
    
    //断言返回的count与数据库的count是否一致
    //if(count.equals("12/17")){
    if(count.equals("sqlcount")){
        Failure=false;
        log.info("数据一致"+"-----count的值为:"+count+"------sqlcount的值为:"+sqlcount);
    }
    else{
        Failure=true;
        FailureMessage="不相等呀,请检查!!!"+"count的值为:"+count+"------sqlcount的值为:"+sqlcount;
        log.info(FailureMessage);
    }

    四、线程组框架展示:

  • 相关阅读:
    CCF CSP 201503-1 图像旋转
    CCF CSP 201403-1 相反数
    CCF CSP 201312-1 出现次数最多的数
    CCF CSP 201703-3 Markdown
    CCF CSP 201709-3 JSON查询
    CCF CSP 201709-2 公共钥匙盒
    CCF CSP 201709-1 打酱油
    CCF CSP 201604-4 游戏
    CCF CSP 201604-1 折点计数
    CCF CSP 201612-1 中间数
  • 原文地址:https://www.cnblogs.com/Chilam007/p/14063947.html
Copyright © 2020-2023  润新知