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
$['store']['book'][0]['title']
这里我习惯用第一种,也推荐使用,比较类似编程时的方法调用;用 $
表示从根元素开始找,.
点上要找的元素,一层一层的找下去,直到达到你需要找的地方;同样的元素可以根据中括号[]+索引
的方法来区分,索引也是从0开始;
-
操作符,官方提供了如下操作符
-
实操演示
以下实操演示均先分为以下三步:
- 以
Jayway JsonPath
的parse方法对json文件内容进行解析获取 - 再使用
set
方法以Jayway JsonPath
的语法对解析结果进行修改 - 最后使用阿里的
fastJson
对结果进行格式化输出,查看修改结果
1)$.store.book[*].author ——所有书的作者
将所有书的作者名都改为"测试作者"@Test void jsonPath() throws IOException { //jayway jsonpath DocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json")); documentContext.set("$.store.book[*].author","测试作者"); String jsonString = documentContext.jsonString(); //ali fastJson JSONObject 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
@Test void jsonPath() throws IOException { //jayway jsonpath DocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json")); documentContext.set("$.store.*","all change"); String jsonString = documentContext.jsonString(); //ali fastJson JSONObject 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
@Test void jsonPath() throws IOException { //jayway jsonpath DocumentContext documentContext = JsonPath.parse(this.getClass().getResourceAsStream("/book.json")); documentContext.set("$..book[0,1]","first two change"); String jsonString = documentContext.jsonString(); //ali fastJson JSONObject object = JSONObject.parseObject(jsonString); String pretty = com.alibaba.fastjson.JSON.toJSONString(object, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat); System.out.println(pretty); }
运行结果:
2.2 补充说明
上述举了几个简单的例子,在日常工作中用的最多的就是对模板中的部分字段进行修改,其余不常变动的字段可在模板文件中设置;
在官网中还提供了很多算数方法和逻辑符号,如有需要可在官网中继续学习研究:3、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
执行输出
运行结果:@Test void 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就会自动提示你需要插件,提示安装的,都不需要你自己去找,方便~) - 插件安装成功后,文件的表现如下:
进入查看文件内容,根据我们以往的经验,第一反应就是成了!应该可以了: - 当然,感觉归感觉,还是要实际测试下:
运行结果:@Test void 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、写在最后
参考文档:
JsonPath: https://github.com/json-path/JsonPath
Mustache: https://github.com/spullara/mustache.java
来源:CSDN
作者:TesterAllen
链接:https://blog.csdn.net/weixin_43291944/article/details/103967122