最近團隊開發了一個平台,功能界面類似
postman
,用例都還是單接口的用例,就是可以綁定一個使用者的登入狀态和一些常量。驗證功能主要分為兩類:1、系統驗證(包括請求異常、HTTP狀态碼、通用響應結構驗證);2、功能驗證(包括業務code、文本内容等)。都是通過字元串解析和正則比對來完成的。
接下來的二期有一個目标就是豐富驗證功能和多用例串聯起來,這裡了解到了一個
jsonpath
的工具,經過簡單嘗試,效果非常理想。因為每一個用例都對應這一個請求,執行完都會傳回一個
JSonobject
的對象(這裡是架構封裝好的)。如果使用
JSonpath
的标記語言能夠完成
json
資訊的提取,那麼就可以完美解決這個需求。
下面分享一下官方的
API
的實踐。
引入jar包
compile group: 'com.jayway.jsonpath', name: 'json-path', version: '2.4.0'
複制
json資料
首先看官方給的
json
資料的
Demo
(我做了一點點修改):
JSONObject json = JSON.parseObject("{" +
" \"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," +
" \"ss\": [32,32,4,23]" +
"}");
複制
jsonpath
的兩種寫法
jsonpath
JsonPath
表達式始終以與
XPath
表達式與
XML
文檔結合使用的方式解析
JSON
結構資料。
JsonPath
中的根對象或者數組用$表示。
JsonPath
表達式可以使用點符号
$.store.book[0].title
或括号符号
$['store']['book'][0]['title']
API
基本的是一個
read()
方法:
/**
* Creates a new JsonPath and applies it to the provided Json object
*
* @param json a json object
* @param jsonPath the json path
* @param filters filters to be applied to the filter place holders [?] in the path
* @param <T> expected return type
* @return list of objects matched by the given path
*/
@SuppressWarnings({"unchecked"})
public static <T> T read(Object json, String jsonPath, Predicate... filters) {
return parse(json).read(jsonPath, filters);
}
複制
- 對于測試來講,隻需要兩個參數即可,足夠滿足所有使用場景了,而且後面的參數對象對于
相容性不咋好,部分進階文法不支援這個。fastjson
擷取所有圖書的作者清單
jsonpath
:
$.store.book[*].author
代碼:
Object read = JsonPath.read(json, "$.store.book[*].author");
output(read);
複制
這裡可以完全自定義傳回對象類型,
jsonpath
會自動幫使用者完成對象轉換,跟下面的這個寫法是完全等效的。
List read = JsonPath.read(json, "$.store.book[*].author");
output(read);
複制
輸出:
INFO-> 目前使用者:fv,IP:10.60.192.21,工作目錄:/Users/fv/Documents/workspace/fun/,系統編碼格式:UTF-8,系統Mac OS X版本:10.15.6
INFO-> ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
複制
可以看到得到了無論使用
object
或者
list
得到的結果都是一樣的,但是如果使用的不當的對象類型,就會報下面的錯誤:
Exception in thread "main" java.lang.ClassCastException: net.minidev.json.JSONArray cannot be cast to java.lang.String
at com.fun.ztest.groovy.JsonPathTest.main(JsonPathTest.java:50)
複制
擷取所有作者
JSonpath:..author.store..price
代碼省略,輸出:
INFO-> 目前使用者:fv,IP:10.60.192.21,工作目錄:/Users/fv/Documents/workspace/fun/,系統編碼格式:UTF-8,系統Mac OS X版本:10.15.6
INFO-> ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]
複制
INFO-> 目前使用者:fv,IP:10.60.192.21,工作目錄:/Users/fv/Documents/workspace/fun/,系統編碼格式:UTF-8,系統Mac OS X版本:10.15.6
INFO-> [19.95,8.95,12.99,8.99,22.99]
複制
可以看到可以不指定具體的
key
也可以擷取固定層級的某個
key
的
value
。
擷取節點下所有資訊
-
:JSonpath
$.store.*
-
:JSonpath
$.ss.*
代碼省略,輸出:
INFO-> 目前使用者:fv,IP:10.60.192.21,工作目錄:/Users/fv/Documents/workspace/fun/,系統編碼格式:UTF-8,系統Mac OS X版本:10.15.6
INFO-> [{"color":"red","price":19.95},[{"author":"Nigel Rees","price":8.95,"category":"reference","title":"Sayings of the Century"},{"author":"Evelyn Waugh","price":12.99,"category":"fiction","title":"Sword of Honour"},{"author":"Herman Melville","price":8.99,"isbn":"0-553-21311-3","category":"fiction","title":"Moby Dick"},{"author":"J. R. R. Tolkien","price":22.99,"isbn":"0-395-19395-8","category":"fiction","title":"The Lord of the Rings"}]]
複制
INFO-> 目前使用者:fv,IP:10.60.192.21,工作目錄:/Users/fv/Documents/workspace/fun/,系統編碼格式:UTF-8,系統Mac OS X版本:10.15.6
INFO-> [32,32,4,23]
複制
下期講講如果處理
json
數組,歡迎繼續關注!