在做接口自動化測試時,我們需將測試用例的預期結果與實際結果進行對比,如果一致就認定測試用例通過,不一致就認定失敗。而后端接口返回的數據一般是以json的方式返回到前端,那么用jsonpath來做預期結果的處理就很適合了,尤其是對於復雜的json串,jsonpath的優勢更明顯。
Jsonpath:看它的名字你就能知道,這家伙和JSON文檔有關系,正如XPath之於XML文檔一樣,JsonPath為Json文檔提供了解析能力,通過使用JsonPath,你可以方便的查找節點、獲取想要的數據,JsonPath是Json版的XPath。
JsonPath語法要點:
-
$ 表示文檔的根元素
-
@ 表示文檔的當前元素
-
.node_name 或 ['node_name'] 匹配下級節點
-
[index] 檢索數組中的元素
-
[start:end:step] 支持數組切片語法
-
* 作為通配符,匹配所有成員
-
.. 子遞歸通配符,匹配成員的所有子元素
-
(<expr>) 使用表達式
-
?(<boolean expr>)進行數據篩選
下面分別用Java與Python實現以Jsonpath的方式處理預期結果
# java代碼 import com.alibaba.fastjson.JSONPath; import org.junit.jupiter.api.Test; import java.util.HashMap; import java.util.Map; public class JSONPathUtil { public static Boolean checkPoint(String response, String checkData) throws Exception { //分隔檢查點 String[] data = checkData.split(";"); //設置標記 Boolean flag = false; Map<String, Object> map = new HashMap<>(); for (int i = 0; i < data.length; i++) { map.put(data[i].split("=")[0], data[i].split("=")[1]); System.out.println("檢查點" + (i + 1) + "實際結果:" + JSONPath.read(response, data[i].split("=")[0])); System.out.println("檢查點" + (i + 1) + "預期結果:" + map.get(data[i].split("=")[0])); if (JSONPath.read(response, data[i].split("=")[0]) instanceof String) { if (JSONPath.read(response, data[i].split("=")[0]).equals(map.get(data[i].split("=")[0]))) { flag = true; } else { flag = false; } } else { if ((JSONPath.read(response, data[i].split("=")[0]).toString()).equals(map.get(data[i].split("=")[0]))) { flag = true; } else { flag = false; break; } } } return flag; } @Test public void testCheckPoint() { String json = "{\"store\":{\"book\":[{\"title\":\"高效Java\",\"price\":10.0},{\"title\":\"設計模式\",\"price\":12.21},{\"title\":\"重構\",\"isbn\":\"553\",\"price\":8},{\"title\":\"虛擬機\",\"isbn\":\"395\",\"price\":22}],\"bicycle\":{\"color\":\"red\",\"price\":19}}}"; String params = "$.store.book[0].price=10.0;$.store.book[1].title=設計模式"; Boolean flag = null; try { flag = checkPoint(json, params); } catch (Exception e) { e.printStackTrace(); } if (flag) { System.out.println("測試執行結果:成功"); } else { System.out.println("測試執行結果:失敗"); } } }
下面是python代碼
import jsonpath def get_instance(value, check): flag = None if isinstance(value, str): if check == value: flag = True else: flag = False elif isinstance(value, float): if value - float(check) == 0: flag = True else: flag = False elif isinstance(value, int): if value - int(check) == 0: flag = True else: flag = False return flag def check(response, checkPoint): c = checkPoint.split(";") flag = None for i in range(0, len(c)): checkPoint_dict = {} checkPoint_dict[c[i].split("=")[0]] = c[i].split("=")[1] list = jsonpath.jsonpath(response, c[i].split("=")[0]) value = list[0] check = checkPoint_dict[c[i].split("=")[0]] print("檢查點{}:實際結果:{}, 預期結果:{}".format(i + 1, value, check)) flag = get_instance(value, check) if flag: print("測試執行結果:成功") else: print("測試執行結果:失敗") if __name__ == '__main__': response = {"store": {"book": [{"title": "高效Java", "price": 10.0}, {"title": "設計模式", "price": 12.21}, {"title": "重構", "isbn": "553", "price": 8}, {"title": "虛擬機", "isbn": "395", "price": 22}], "bicycle": {"color": "red", "price": 19}}} checkPoint = "$.store.book[0].price=10.0;$.store.book[1].title=設計模式1"; check(response, checkPoint)