写点什么

接口自动化测试 | JsonPath 与 Mustache 请求传参的模板化技术

  • 2023-02-08
    北京
  • 本文字数:3407 字

    阅读完需:约 11 分钟

1.需求背景


图片


在实际的接口测试时,传参有时候可能需要很多,也可能我们就是想要一份完整的参数,必填项和非必填项都包含在内,比如下面的 json:


{"store": {"book": [{"category": "reference","author": "Nigel Rees","title": "Sayings of the Century","price": 8.95},{"category": "fiction","author": "Evelyn Waugh","title": "Sword of Honour","price": 12.99},{"category": "fiction","author": "Herman Melville","title": "Moby Dick","isbn": "0-553-21311-3","price": 8.99},{"category": "fiction","author": "J. R. R. Tolkien","title": "The Lord of the Rings","isbn": "0-395-19395-8","price": 22.99}],"bicycle": {"color": "red","price": 19.95}},"expensive": 10}


一个个在方法中传入显然不现实;写入 hashmap 中传入的话工作量和复杂度也很大,这个时候就需要一个模板,把我们需要的参数和结构提前定义好,我们只需要修改其中对应的值即可,这就要引出今天的两位主角:


JsonPath


Mustache


2.JsonPath


图片


先来看第一个模板技术 JsonPath,注意这里的 JsonPath 指的是 Jayway JsonPath,maven 依赖如下:


<dependency><groupId>com.jayway.jsonpath</groupId><artifactId>json-path</artifactId><version>2.4.0</version></dependency>


2.1 元素定位


在 UI 自动化中我们会使用到 xpath 的元素定位的技术,在这里我将其类比过来方便理解记忆;Jayway JsonPath 为我们提供了两种定位的写法:['store']['book'][0]['title']


这里我习惯用第一种,也推荐使用,比较类似编程时的方法调用;


用 $ 表示从根元素开始找,. 点上要找的元素,一层一层的找下去,直到达到你需要找的地方;同样的元素可以根据中括号[]+索引的方法来区分,索引也是从 0 开始;


操作符,官方提供了如下操作符


图片


实操演示


以下实操演示均先分为以下三步:


以 Jayway JsonPath 的 parse 方法对 json 文件内容进行解析获取


再使用 set 方法以 Jayway JsonPath 的语法对解析结果进行修改


最后使用阿里的 fastJson 对结果进行格式化输出,查看修改结果


1)$.store.book[*].author ——所有书的作者将所有书的作者名都改为"测试作者"


@Testvoid jsonPath() throws IOException {//jayway jsonpathDocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json"));documentContext.set("$.store.book[*].author","测试作者");String jsonString = documentContext.jsonString();


//ali fastJsonJSONObject object = JSONObject.parseObject(jsonString);String pretty = com.alibaba.fastjson.JSON.toJSONString(object, SerializerFeature.PrettyFormat,        SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);System.out.println(pretty);
复制代码


}


运行结果:


图片


2)$.store.*——store 下所有的都进行修改,这里包括了 bicycle 和 book。将 store 下的所有内容改为 all change


@Testvoid jsonPath() throws IOException {//jayway jsonpathDocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json"));documentContext.set("$.store.*","all change");String jsonString = documentContext.jsonString();


//ali fastJsonJSONObject object = JSONObject.parseObject(jsonString);String pretty = com.alibaba.fastjson.JSON.toJSONString(object, SerializerFeature.PrettyFormat,        SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);System.out.println(pretty);
复制代码


}


运行结果:


图片


3)$…book[0,1]——book 下的第一个和第二个将 book 下的第一个和第二个内容改为 first two change


@Testvoid jsonPath() throws IOException {//jayway jsonpathDocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json"));documentContext.set("$..book[0,1]","first two change");String jsonString = documentContext.jsonString();


//ali fastJsonJSONObject object = JSONObject.parseObject(jsonString);String pretty = com.alibaba.fastjson.JSON.toJSONString(object, SerializerFeature.PrettyFormat,        SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);System.out.println(pretty);
复制代码


}运行结果:


图片


2.2 补充说明


上述举了几个简单的例子,在日常工作中用的最多的就是对模板中的部分字段进行修改,其余不常变动的字段可在模板文件中设置;在官网中还提供了很多算数方法和逻辑符号,如有需要可在官网中继续学习研究:


图片


图片


  1. Mustache


图片上面介绍了 JsonPath 的模板技术,但是有一个缺点,就是 JsonPath 只能处理 json 格式的模板文件,如果是非 json 的就不行了,这时候就需要有一个通用的模板技术,这就是 Mustache 了


Mustache,字面意思是大胡子,可能是因为它的模板符号是花括号,比较像大胡子吧,例如官网的首页这张图:


例如官网的首页这张图:


图片


引出这张图,还为了说明一点,可以看出 Mustache 支持各种语言,常用的几乎都能囊括其中,这里有 Java 为例进行研究,maven 依赖如下:


Java 8+:


<dependency><groupId>com.github.spullara.mustache.java</groupId><artifactId>compiler</artifactId><version>0.9.6</version></dependency>


Java 6/7:


<dependency><groupId>com.github.spullara.mustache.java</groupId><artifactId>compiler</artifactId><version>0.8.18</version></dependency>


3.1 实操演示


首先,在需要修改的文件中,将要修改的字段用双花括号{{变量名}}的形式表示,例如这里我们将 book 下第一个商品的 author 和 price 进行变量化


图片


创建 HashMap,将要修改的字段存入 map 中


HashMap<String,Object> map = new HashMap<>();map.put("author","mustacheAuthor");map.put("price",56.8f);


创建 DefaultMustacheFactory 对象


MustacheFactory mf = new DefaultMustacheFactory();


compile 方法编译文件内容,execute 执行输出


@Testvoid mustacheTest() throws IOException {HashMap<String,Object> map = new HashMap<>();map.put("author","mustacheAuthor");map.put("price",56.8f);


MustacheFactory mf = new DefaultMustacheFactory();Mustache mustache = mf.compile("book.json");Writer writer = new OutputStreamWriter(System.out);mustache.execute(writer, map);writer.flush();
复制代码


}


运行结果:


图片


这里看似是成功了,但是仔细看会有问题,price 应该是浮点型,而修改后的类型是 String 类型,这是因为我们在写变量的时候就已经包在了字符串中:


图片


那如果把字符串给去了呢?如下:


图片


很可惜,json 文件会报错!


所以我们还需要引入一个插件,并将文件的后缀名改为 mustache(其实在你该后缀名后 IDE 就会自动提示你需要插件,提示安装的,都不需要你自己去找,方便~)


图片


插件安装成功后,文件的表现如下:


图片


进入查看文件内容,根据我们以往的经验,第一反应就是成了!应该可以了:


图片


当然,感觉归感觉,还是要实际测试下:


@Testvoid mustacheTest() throws IOException {HashMap<String,Object> map = new HashMap<>();map.put("author","mustacheAuthor");map.put("price",56.8f);


MustacheFactory mf = new DefaultMustacheFactory();Mustache mustache = mf.compile("book.mustache");Writer writer = new OutputStreamWriter(System.out);mustache.execute(writer, map);writer.flush();}
复制代码


运行结果:


图片


这个结果就很舒畅了,满足需求,解决问题,get 一项新技能!


4.1 优缺点对比


如果实践了上面的两种模板方法会发现两者在使用上的优缺点:


优点:


JsonPath:可设置默认值,在 json 文件中可提前设置好默认值,字段不修改就使用默认值,需要修改再进行修改


Mustache:不受文件格式的影响,字段替换逻辑也简单清晰


缺点:


JsonPath:只适用于 json 文件


Mustache:灵活度不如 JsonPath,提前必须指定好需要修改的字段


总结:


如果接口的请求体都是以 json 为主的,那么我个人推荐使用 JsonPath,更灵活的控制接口参数的修改程度;当遇到非 json 格式的文件时可用 Mustache 来解决模板化的问题,只是灵活度要稍稍下降一点了可能。


4.2 参考文档


JsonPath | https://github.com/json-path/JsonPathMustache | https://github.com/spullara/mustache.java

用户头像

社区:ceshiren.com 微信:ceshiren2021 2019-10-23 加入

微信公众号:霍格沃兹测试开发 提供性能测试、自动化测试、测试开发等资料,实时更新一线互联网大厂测试岗位内推需求,共享测试行业动态及资讯,更可零距离接触众多业内大佬。

评论

发布
暂无评论
接口自动化测试 | JsonPath 与 Mustache 请求传参的模板化技术_霍格沃兹测试开发学社_InfoQ写作社区