京东质量社区 jmeter 接口自动化测试方案一 (数据驱动版本)

taki for 京东 · 2017年03月26日 · 最后由 congyi1022 回复于 2020年04月01日 · 7818 次阅读

jmeter 是一个非常轻巧好用的性能测试工具,当然也可以做接口自动化测试,这里面我们主要想做一个通用的执行引擎

这么做的好处就是我们不用再关注测试脚本的内容,属于用测试用例的数据去驱动我们执行的走向,这个适合单个接口的测试,但是这个肯定不是很灵活适合代码基础弱一些的同学直接使用,真正的灵活还是要代码去做


一.首先我们要有一个接口测试用例存放的地方,我们这里用 EXCEL 模板管理,里面包含用例名、协议、入参、预期结果、SQL、数据库预期结果,那么我们想在这里面写完可以马上执行测试用例,并且这个执行引擎是比较通用的

二.接下来创建执行计划,先看下做好的

三.下面是具体的 Jmeter 设置

  • 1.设置线程,我们要从参数化文件里面读取用例集,并且以用例的数量作为执行结束,所以线程这里面要一致循环

  • 2.设置参数化文件,主要 4 个参数 文件路径、是否允许循环取值、读取结束是否停止,我们是按照参数化文件用例的数据决定运行多少次,所以不能允许循环取值,读到最后一行停止测试,里面通过一些变量获取参数的值,具体对应关系大家参考用例模板

  • 3.加上协议控制器,具体是哪个协议根据测试用例里面的匹配

  • 4.对于 http 的请求分为 get、post 等多个方法,要加上方法控制器,3.1 的 jmeter 应该不用了

  • 5 取样器的设置全部参数化

  • 6 那么需要做一些断言的处理,这里面弄的简单的响应断言,当然也可以根据情况增加其他的断言

  • 7 下面加上数据库的校验,首先要配置数据库连接配置,取样器后面加上 SQL 后置处理器



  • 8 数据库的断言我们需要用后置处理器的 beanshell 处理,检查是否校验数据库,校验的话通过测试用例里面的预期结果 JSON 和数据库实际的结果对比,不一致修改结果,code506 是我自己定义的 code 码,即使断言过了,也会修改当前的结果为 false,这里用到了 fastjson 所以需要导入包
import com.alibaba.fastjson.JSON;   //引入JSON的类
String checkDb=vars.get("checkDb");  //获取是否校验数据库
log.info("checkDb:"+checkDb);    //为了方便调试 我把信息输出了
if(checkDb.equals("true")){   //判断是否检查数据库
    log.info("进入校验数据库"); //为了方便调试
    String preDbMap=vars.get("DbMap"); //拿到预期数据库的值
   int paramSize =bsh.args.length;  //它是一个数组 
   if(paramSize>0){       //大于0 说明是有预期结果的
    preDbMap =bsh.args[0];
    }else{
        preDbMap="没有预期数据库结果!!!!!";  //小于0 认为没有预期结果
    }  
    preDbMap =preDbMap.trim();  //把预期结果去掉空格
    log.info("preDbMap:"+preDbMap); //为了方便调试
    List results=vars.getObject("resultList");  //拿到数据库返回的List对象,是查询数据库之后的数据
    log.info("results对象:"+results);    //为了方便调试
    if(null!=results){  //如果results 等于null 说明数据库没有查询到数据,可能是绑定或者插入没有成功
        int size=results.size();     //获取他的长度
        log.info("results的SIZE:"+size); //为了方便调试
        if(size>0){      
            log.info("进入到SIZE了:");
            for(Map m:results){   //因为返回的List对象里面是一个MAP,所以是key和value的形式,可以用MAP的方式遍历循环
                String dbMap =JSON.toJSONString(m); //拿到第一个对象的Map 进行转JSON字符串
                dbMap =dbMap.trim(); //去掉空格
                log.info("数据库JSON:"+dbMap); //为了方便调试
                if(!preDbMap.equalsIgnoreCase(dbMap)){  //用预期的JSON串和查询到的结果JSON串进行对比
                    //如果不一样的情况下,说明数据库的断言失败,可能是程序的问题
                    String result =prev.getResponseDataAsString();   //拿到实际结果的值,用于存放到返回数据中
                prev.setResponseCode("506");            //我们自定义了一个CODE码,告诉结果显示的CODE是这个
                    prev.setSuccessful(false);   //设置结果为错误
                    prev.setResponseMessage("接口断言通过,数据库校验未通过");  //设置一个提示信息,大概是说明原因导致的
                    //写入结果返回的结果,还有数据库校验未通过,我们的预期数据库的值是,实际的值是,加上这个是为了方便定位问题
            prev.setResponseData(result+",\n数据库校验未通过,\n预期值:"+preDbMap+",\n实际值:"+dbMap);
                    }       
                }       
        }else{
            //当SIZE没有大于0的时候,说明也没有查询出来数据,可能没有绑定成功。
            log.info("没有到SIZE了:");
            //设置结果为错误
            prev.setSuccessful(false);
            //设置提示信息
            prev.setResponseData("数据库没有返回信息,接口result:"+result);
        }
    }else{
        log.info("result为null");
            prev.setSuccessful(false);
            prev.setResponseData("数据没有返回信息,接口result:"+result);
        }
}else{
    //当checkDb不等于true的情况下,可能是用户设置了这条用例不需要检查数据库
    log.info("没有进入判断");
    }

  • 9.我们通过查看结果树查看报告,大家看左侧的树就是我们的用例名称,具体的响应结果断言是通过的,但是数据库校验没有通过



  • 10.邮件报告,这个邮件用 ant 去做的,不过需要修改些东西,下个文章在介绍,给大家先看下效果,邮件有两部分,邮件正文和附件 (详细的 HTML 报告)
共收到 43 条回复 时间 点赞

复杂业务场景怎么做,比如需要预置回收的,多条用例依赖的,或者直接多个步骤才组成一条用例的情况,这样断言类型是不是也限定的少了点会

taki #44 · 2017年03月26日 Author
北溟 回复

对,所以文章开头说了适合单个接口的简单场景,断言复杂的直接在 beanshell 里面加,Jmeter 本身自带的断言也不是很好,预埋数据之类的可以在前面加上前置处理器或者在抽出来个取样器可以做,真正的灵活还是代码,这个适合即来则用

taki 回复

哦哦,手机上没看仔细,你还加粗了

匿名 #41 · 2017年03月27日

String preDbMap=vars.get("DbMap"); //拿到预期数据库的值 这句可以解释下吗?DbMap 是从哪来的?求大神解答

taki #22 · 2017年03月27日 Author

vars 是 Jmeter 的内置变量,相当于 map , DbMap 是从测试用例里面拿到的数据库值的预期结果

匿名 #39 · 2017年03月27日
taki 回复

谢谢

38楼 已删除

dbmap 从哪取的

应该是 csvsetdata 那张图里少写了个变量吧,用例的最后一个字段

taki #24 · 2017年03月27日 Author
北溟 回复

是的,才发现参数化文件少写了一个 Dbmap

taki #34 · 2017年03月27日 Author

CSV 取的,才发现参数化文件少写了一个 Dbmap 变量

taki 回复

取 db 数据的过程是什么样子的 用 jdbc 还是有什么封装的函数

taki #14 · 2017年03月27日 Author

自带的那个 JDBC,用 SQL 查询出来的值转成 JSON,然后预期 DB 的值也是 JSON,对比两个 JSON 确认是否通过

taki 回复

我最近也在设计这个功能 所以关注这块 如何优雅的访问 db 等第三方数据源 我搞了一个配置驱动的接口测试框架

taki #30 · 2017年03月27日 Author

脱离 Jmeter 之外的吧,求分享哈

taki 回复

搞了一个通用的框架 底层可以调用其他框架 力求简约 过阵子我在沙龙上介绍下 想了不少改进点

CSV 文件里入参是一个 JSON,然后在 POST 请求时,Body Data 直接使用 ${param},这个不需要提前把 JSON 处理成 key=value 的格式吗?

taki #27 · 2017年03月29日 Author
露重烟轻 回复

需要

taki 回复

请问是在 BeanShell PreProcessor 里面用脚本处理的吗?还是说有其它更方便的方法?

taki #25 · 2017年03月29日 Author

没太懂问题是什么

taki 回复

抱歉,我没说明白。我想问的是怎么把入参里面的 JSON 转成 key=value 格式的,是利用 BeanShell PreProcessor,在里面用脚本处理的吗?还是说有其它更方便的方法?

taki #23 · 2017年03月29日 Author

这里面的入参在用例的 EXCEL 里面就是转完成 的

我的 delimit 分隔符要设置成 “,” “@” 这个不行是为啥?

test_ray 回复

这个跟你 csv 文件里使用的是哪个分隔符有关吧,一般默认是逗号【,】,但是因为测试数据的入参和预期结果里面有逗号【,】,所以建议使用 @ 作为分隔符

我的 csv data set config 里的 filename 使用参数不成功是怎么回事,不能用 ${filename}

确实是只适合简单点的场景和系统,看到京东这种大厂都这么玩,我觉得自己 1 面前的想法(实践了两个版本)是可推广落地的。

ant 生成 html 报告那么完美!!!xml 能分享一下吗测试大神

想问下,接口如果有校验值,这个怎么做呢?是写接口的时候,提前把校验值计算出来么?

还有如果接口是插入数据值的话,接口想重复执行,要么改入参要么清数据库,这个是怎么实现的呢?

仅楼主可见

请问 json path extractor 中的配置可以看一下吗?或者可以的话直接把测试计划发出,谢谢指教

taki #12 · 2018年03月20日 Author
luoxi001713 回复

用前置处理器可以做

taki #11 · 2018年03月20日 Author
mao 回复

这个主要是做断言,计划找到发给你

taki #6 · 2018年03月20日 Author
mao 回复

目前没有环境了,主要做断言用的

楼主,能否把测试计划也发我一份,谢谢了

仅楼主可见

楼主,从 csv 文件获取数据库预期值后,获取数据库预期值长度 int paramSize = bsh.args.length,这一句的 bsh 是哪里来的?

taki #6 · 2018年06月21日 Author
yangxiaoyun 回复

jmeter beanshell 内置方法

仅楼主可见
taki #4 · 2018年06月22日 Author
yangxiaoyun 回复

bsh.args.length 的用法你百度查询一下吧

你好,博主,我如果接口是第二个接口用第一个接口返回的字段,是多个字段,怎么整

taki #2 · 2018年07月05日 Author
BigFaceHL 回复

和正常的获取取样器数据一样,不过设计的思路就要改一下了

“第二个接口用第一个接口返回的字段作为参数”
“和正常的获取取样器数据一样,不过设计的思路就要改一下了”

请问楼主,应该是什么样的设计思路呢?入门测试小白想不出来 o(╥﹏╥) o

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册