前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你真的会写接口自动化测试断言吗?

你真的会写接口自动化测试断言吗?

作者头像
一个正经的测试
发布2024-01-22 16:55:57
1770
发布2024-01-22 16:55:57
举报

你真的会写自动化测试断言吗?

在接口测试中,断言是一项非常重要的操作,它是用来校验接口返回结果是否符合预期的一种手段。一般来说,接口测试断言大致可以分为以下几类:

  1. 状态码断言:这是最基本也是最常用的一种断言方式。大部分情况下,接口返回的HTTP状态码可以用来判断接口请求是否成功。
  2. 响应体断言:基于接口的响应数据进行校验。
  3. 响应时间断言:接口响应时间是否在可接受的范围之内。
  4. 数据库断言:接口调用后,数据是否有相应的变化。

这种使用断言来进行接口测试的方法,在测试框架中的具体实现可能各不相同。

下文将以Python的requests模块来做一个简单的例子。

首先,我们需要构造一个基本的GET请求,并获取响应:

代码语言:javascript
复制
import requests

response = requests.get('http://api.example.com/data')

在得到了响应后,我们可以使用Python的assert关键字来进行断言。比如我们可以断言状态码是200:

代码语言:javascript
复制
assert response.status_code == 200
assert response.status_code == 200

如果状态码不是200,那么这个语句会抛出AssertionError

我们也可以断言响应的JSON数据中包含了某个特定的键:

代码语言:javascript
复制
data = response.json()
assert 'key' in data

同样,如果'key'不在data中,那么这个语句也会抛出AssertionError。对于更复杂的断言,我们可能需要使用一些第三方库来帮助我们。比如我们可以使用jsonschema库来断言响应数据符合某个JSON Schema:

代码语言:javascript
复制
from jsonschema import validate

schema = {
    "type" : "object",
    "properties" : {
        "key" : {"type" : "string"},
    },
    "required": ["key"]
}

validate(data, schema)

那么,对于更复杂的断言,我们该怎么做呢?

对于JSON响应断言,主要是确认返回的JSON对象中的某个或者某些元素是否和预期的一致。这种断言的方式,最常见的就是比对键值对是否相符了。举个例子,假设我们期待的JSON响应如下

代码语言:javascript
复制
{
    "title": "foo",
    "body": "bar",
    "userId": 1
}

我们可以使用Python来做一个简单的断言操作:

代码语言:javascript
复制
expected_json = {
    "title": "foo",
    "body": "bar",
    "userId": 1
}

response_json = response.json()

assert response_json == expected_json

在上述代码中,response.json()用来从响应中获取JSON数据,然后使用assert语句来断言这个JSON数据和我们期待的JSON数据是否相同。

如果我们只关心返回结果中的某一部分,例如,我们只关心返回结果中的title字段,那么我们可以做如下断言:

代码语言:javascript
复制
assert response_json['title'] == expected_json['title']
assert response_json['title'] == expected_json['title']

对于更复杂的JSON响应断言,比如,JSON响应为嵌套结构,或者是JSON数组,我们可能需要进行递归或者遍历等操作来进行断言,这种情况下可以使用一些第三方的断言库来提升我们的效率。比如Python的jsonpath库,可以帮助我们快速的定位JSON中的某一段数据,并进行断言

JsonPah是一种信息检索语言,可以让你用一个类似XPath的语法快速定位JSON结构中的部分内容。处理嵌套结构的JSON响应时,JsonPath提供了一种简单有效的方法。重要的是理解JsonPath的语法,比如 '$' 表示根节点,'.' 或 '[]' 用于访问子节点,'*' 用于通配等。

下面举个例子来说明如何使用JsonPath:假定我们有一个如下的复杂JSON:

代码语言:javascript
复制
response_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",
                "price": 8.99
            },
            {
                "category": "fiction",
                "author": "J. R. R. Tolkien",
                "title": "The Lord of the Rings",
                "price": 22.99
            }
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    },
}

如果我们需要取出所有书的标题(title),可以使用如下语句:

代码语言:javascript
复制
from jsonpath import jsonpathtitles = jsonpath(response_json, '$.store.book[*].title')print(titles) #输出:['Sayings of the Century', 'Sword of Honour', 'Moby Dick', 'The Lord of the Rings']
from jsonpath import jsonpath

titles = jsonpath(response_json, '$.store.book[*].title')

print(titles) #输出:['Sayings of the Century', 'Sword of Honour', 'Moby Dick', 'The Lord of the Rings']

如果我们需要取出价格大于10的书的标题,可以使用如下语句:

代码语言:javascript
复制
titles = jsonpath(response_json, "$.store.book[?(@.price > 10)].title")print(titles) # 输出:['Sword of Honour', 'The Lord of the Rings']
titles = jsonpath(response_json, "$.store.book[?(@.price > 10)].title")

print(titles) # 输出:['Sword of Honour', 'The Lord of the Rings']

JsonPath非常简洁高效,能让我们的断言操作更简单,代码更清晰,既然这么强大的话

这不得有个使用方法

不着急,下面给你列出了常用的通配符的解析说明

JsonPath表达式中的通配符通常有以下几种:

  1. *:通配符,匹配所有的对象或元素。比如 $..book[*].author 可获取所有作者的名字。
  2. ..:深度操作符,无论深度多少层,都可以匹配到路径。比如 $..author 可获取所有的作者信息。
  3. . 或 []:逐层向下遍历,. 针对于名字,[] 针对于数组下标或者名称。比如 $['store']['book'][0]['price'] 获取第一本书的价格。
  4. @:现行节点信息,常在过滤器中使用,比如 $..book[?(@.price<10)] 意思是获取所有价格小于10的书。
  5. ():表达式组,用于根据自定义表达式过滤。比如 $..book[(@.length-1)] 获取最后一本书。
  6. ?():过滤操作符,用于查找符合条件的元素。比如 $..book[?(@.isbn)] 获取所有包含ISBN的书。

以上这些通配符让我们在使用JsonPath时有更大的灵活性,可以在大型或者嵌套较深的JSON数据中准确地定位我们所需要的数据。

那么,面试会怎么问呢

举个例子:

面试官

JsonPath表达式中的深度操作符..可以匹配到多少层的路径?

YOU

:在JsonPath中,深度操作符 .. 在不知道精确路径或者需要查询多层嵌套数据时非常有用。.. 不关心元素在JSON数据中的精确位置,它会「深度搜索」,也就是说,无论数据嵌套在JSON结构的多深,只要符合你的查询条件,它都能找到。

可以用任何的名字或者通配符 * 来配合深度操作符一起使用,它们的组合可以匹配到任何级别的元素。例如,假设我们有一个JSON对象:

代码语言:javascript
复制
{
    "level_1": {
        "level_2": {
            "level_3": {
                "item": "value"
            }
        }
    }
}

如果你不知道 "item" 的精确路径,但你知道它的名字,并且你想从JSON数据中找到它,你可以使用 .. 操作符加上名字进行深度搜索,如:$..item,这将返回所有名为 "item" 的元素,无论它们处在哪一层级。

总的来说,深度操作符 .. 可以匹配到无限多层的路径,这对于处理深层嵌套的数据结构非常有用。

面试官

除了深度搜索,JsonPath还有其他什么功能可以处理深层嵌套的数据结构?

YO

:除了深度搜索外,JsonPath还提供了一些其他功能来处理深层嵌套的数据结构:

  1. 数组索引:JsonPath允许你使用数组索引来访问特定位置的元素。例如,表达式$.store.book[0]将返回图书数组的第一本书。
  2. 多个索引:JsonPath还允许你在同一层级上访问多个元素。例如,$.store.book[0,1]将返回图书数组的前两本书。
  3. 切片操作:JsonPath支持Python风格的切片操作,允许你访问一个连续的元素序列,而不仅仅是单个元素。例如, $.store.book[1:3]将返回图书数组的第二和第三本书。
  4. 过滤表达式:JsonPath支持过滤表达式,允许你使用逻辑运算符和比较运算符来过滤返回的元素。例如,$.store.book[?(@.price < 10)]将返回图书数组中价格低于10的所有书。
  5. 通配符:正如我们前面讨论的,*通配符可以用来匹配任意元素,不论位置。

总的来说,断言是接口测试中的一个重要部分,合理、充分地使用断言,不仅可以提升我们的测试质量,也能帮助我们快速定位问题。同时,塑造良好的断言策略,对于维护和持续提升一个测试框架也是尤为关键的。

如果你还有什么疑问,请从下方留言吧~

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-04,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 一个正经的测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com