欢迎光临散文网 会员登陆 & 注册

技术分享 | 接口自动化测试如何搞定 json 响应断言?

2022-08-03 12:50 作者:爱测软件测试  | 我要投稿

在之前的的章节已经简单介绍了如何断言接口的响应值,在实际工作过程中,json 的响应内容往往十分复杂,面对复杂的 json 响应体,主要通过 JSONPath 解决。JSONPath 提供了强大的 JSON 解析功能,使用它自带的类似 XPath 的语法,可以更便捷灵活的用来获取对应的 JSON 内容。


***环境准备***


Python 版本安装


```

pip install jsonpath


```



Java 版本安装


```

<dependency>

    <groupId>com.jayway.jsonpath</groupId>

    <artifactId>json-path</artifactId>

    <version>2.6.0</version>

</dependency>


```



***XPath 和 JSONPath 语法***



下表是 XPath 和 JSONPath 语法进行对比,这两者的定位方式,有着非常多的相似之处:


![image|800x889](upload://5oVlgIyEqfmWANfdzWFXkIIQ3tU.png)



比如同样一个字段,XPath 中的语法是:


```

/store/book[0]/title


```




JSONPath 的语法是:


```

$.store.book[0].title

$['store']['book'][0]['title']


```




下面是一组 json 结构,分别通过 JSONPath 和 XPath 的方式提取出来


```

{

  "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

    }

  }

}


```




下表列出了 XPath 与 JSONPath 的对比:


![](https://ceshiren.com/uploads/default/original/3X/9/9/995f5f8eb84c11addf91e651421cd69d17b2c78e.png)

***实战练习***

以下是 https://ceshiren.com/t/topic/6950.json 这个接口的正常响应值(因响应篇幅过长,删除了部分内容):


```

{

  'post_stream': {

    'posts': [

      {

        'id': 17126,

        'name': '思寒',

        'username': 'seveniruby',

        'avatar_template': '/user_avatar/ceshiren.com/seveniruby/{size}/2_2.png',

        'created_at': '2020-10-02T04:23:30.586Z',

        'cooked': '<p>一直以来的平均涨薪率在30%以上,这次刷新的记录估计要保持好几年了</p>',

        'post_number': 6,

        'post_type': 1,

        'updated_at': '2020-10-02T04:23:48.775Z',

        'reply_to_post_number': None,

        'reads': 651,

        'readers_count': 650,

        'score': 166.6,

        'yours': False,

        'topic_id': 6950,

        'topic_slug': 'topic',

        'display_username': '思寒',

        'primary_group_name': 'python_12',

        ...省略...

      },

    ],

  },

  'timeline_lookup': ,

  'suggested_topics':,

  'tags': [

    '精华帖',

    '测试开发',

    '测试求职',

    '外包测试'

  ],

  'id': 6950,

  'title': '测试人生 | 从外包菜鸟到测试开发,薪资一年翻三倍,连自己都不敢信!(附面试真题与答案)',

  'fancy_title': '测试人生 | 从外包菜鸟到测试开发,薪资一年翻三倍,连自己都不敢信!(附面试真题与答案)',


}


```

接下来则需要实现一个请求,断言以上的响应内容中 name 字段为'思寒'所对应的 cooked 包含"涨薪"


Python 演示代码

JSONPath 断言

```

import requests

from jsonpath import jsonpath

r = requests.get("https://ceshiren.com/t/topic/6950.json").json()

result = jsonpath(r, "$..posts[?(@.name == '思寒')].cooked")[1]

assert "涨薪" in result

```

 Java 演示代码

JSONPath 断言

```

import com.jayway.jsonpath.JsonPath;

import org.junit.jupiter.api.Test;

import java.util.List;

import static io.restassured.RestAssured.given;

public class jsonTest {

    @Test

    void jsonTest() {

        //获取响应信息,并转成字符串类型

        String res = given().when().

                get("https://ceshiren.com/t/topic/6950.json")

                .then().extract().response().asString();

        //通过jsonpath表达式提取需要的字段

        List<String> result = JsonPath.read(res, "$..posts[?(@.name == '思寒')].cooked");

        // 断言验证

        assert result.get(1).contains("涨薪");

    }

}

```


技术分享 | 接口自动化测试如何搞定 json 响应断言?的评论 (共 条)

分享到微博请遵守国家法律