如何写接口自动化测试断言?
🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快
你真的会写自动化测试断言吗?
在接口测试中,断言是一项非常重要的操作,它是用来校验接口返回结果是否符合预期的一种手段。一般来说,接口测试断言大致可以分为以下几类:
-
状态码断言:这是最基本也是最常用的一种断言方式。大部分情况下,接口返回的HTTP状态码可以用来判断接口请求是否成功。
-
响应体断言:基于接口的响应数据进行校验。
-
响应时间断言:接口响应时间是否在可接受的范围之内。
-
数据库断言:接口调用后,数据是否有相应的变化。
这种使用断言来进行接口测试的方法,在测试框架中的具体实现可能各不相同。
下文将以Python的requests模块来做一个简单的例子。
首先,我们需要构造一个基本的GET请求,并获取响应:
import requests
response = requests.get('http://api.example.com/data')
在得到了响应后,我们可以使用Python的assert关键字来进行断言。比如我们可以断言状态码是200:
assert response.status_code == 200
如果状态码不是200,那么这个语句会抛出AssertionError
。
我们也可以断言响应的JSON数据中包含了某个特定的键:
data = response.json()
assert 'key' in data
同样,如果'key'不在data中,那么这个语句也会抛出AssertionError。对于更复杂的断言,我们可能需要使用一些第三方库来帮助我们。比如我们可以使用jsonschema库来断言响应数据符合某个JSON Schema:
from jsonschema import validate
schema = {
"type" : "object",
"properties" : {
"key" : {"type" : "string"},
},
"required": ["key"]
}
validate(data, schema)
那么,对于更复杂的断言,我们该怎么做呢?
对于JSON响应断言,主要是确认返回的JSON对象中的某个或者某些元素是否和预期的一致。这种断言的方式,最常见的就是比对键值对是否相符了。举个例子,假设我们期待的JSON响应如下
{
"title": "foo",
"body": "bar",
"userId": 1
}
我们可以使用Python来做一个简单的断言操作:
expected_json = {
"title": "foo",
"body": "bar",
"userId": 1
}
response_json = response.json()
assert response_json == expected_json
在上述代码中,response.json()用来从响应中获取JSON数据,然后使用assert语句来断言这个JSON数据和我们期待的JSON数据是否相同。
如果我们只关心返回结果中的某一部分,例如,我们只关心返回结果中的title字段,那么我们可以做如下断言:
assert response_json['title'] == expected_json['title']
对于更复杂的JSON响应断言,比如,JSON响应为嵌套结构,或者是JSON数组,我们可能需要进行递归或者遍历等操作来进行断言,这种情况下可以使用一些第三方的断言库来提升我们的效率。比如Python的jsonpath库,可以帮助我们快速的定位JSON中的某一段数据,并进行断言
JsonPah是一种信息检索语言,可以让你用一个类似XPath的语法快速定位JSON结构中的部分内容。处理嵌套结构的JSON响应时,JsonPath提供了一种简单有效的方法。重要的是理解JsonPath的语法,比如 '$' 表示根节点,'.' 或 '[]' 用于访问子节点,'*' 用于通配等。
下面举个例子来说明如何使用JsonPath:假定我们有一个如下的复杂JSON:
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),可以使用如下语句:
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的书的标题,可以使用如下语句:
titles = jsonpath(response_json, "$.store.book[?(@.price > 10)].title")
print(titles) # 输出:['Sword of Honour', 'The Lord of the Rings']
JsonPath非常简洁高效,能让我们的断言操作更简单,代码更清晰,既然这么强大的话,这不得有个使用方法
不着急,下面给你列出了常用的通配符的解析说明
JsonPath表达式中的通配符通常有以下几种:
- *:通配符,匹配所有的对象或元素。比如 $..book[*].author 可获取所有作者的名字。
- ..:深度操作符,无论深度多少层,都可以匹配到路径。比如 $..author 可获取所有的作者信息。
- . 或 []:逐层向下遍历,. 针对于名字,[] 针对于数组下标或者名称。比如 $['store']['book'][0]['price'] 获取第一本书的价格。
- @:现行节点信息,常在过滤器中使用,比如 $..book[?(@.price<10)] 意思是获取所有价格小于10的书。
- ():表达式组,用于根据自定义表达式过滤。比如 $..book[(@.length-1)] 获取最后一本书。
- ?():过滤操作符,用于查找符合条件的元素。比如 $..book[?(@.isbn)] 获取所有包含ISBN的书。
以上这些通配符让我们在使用JsonPath时有更大的灵活性,可以在大型或者嵌套较深的JSON数据中准确地定位我们所需要的数据。
那么,面试会怎么问呢
举个例子:
面试官:JsonPath表达式中的深度操作符..可以匹配到多少层的路径?
YOU:在JsonPath中,深度操作符 .. 在不知道精确路径或者需要查询多层嵌套数据时非常有用。.. 不关心元素在JSON数据中的精确位置,它会「深度搜索」,也就是说,无论数据嵌套在JSON结构的多深,只要符合你的查询条件,它都能找到。
可以用任何的名字或者通配符 * 来配合深度操作符一起使用,它们的组合可以匹配到任何级别的元素。例如,假设我们有一个JSON对象:
{
"level_1": {
"level_2": {
"level_3": {
"item": "value"
}
}
}
}
如果你不知道 "item" 的精确路径,但你知道它的名字,并且你想从JSON数据中找到它,你可以使用 .. 操作符加上名字进行深度搜索,如:$..item,这将返回所有名为 "item" 的元素,无论它们处在哪一层级。
总的来说,深度操作符 .. 可以匹配到无限多层的路径,这对于处理深层嵌套的数据结构非常有用。
面试官:除了深度搜索,JsonPath还有其他什么功能可以处理深层嵌套的数据结构?
YOU:除了深度搜索外,JsonPath还提供了一些其他功能来处理深层嵌套的数据结构:
-
数组索引:JsonPath允许你使用数组索引来访问特定位置的元素。例如,表达式$.store.book[0]将返回图书数组的第一本书。
-
多个索引:JsonPath还允许你在同一层级上访问多个元素。例如,$.store.book[0,1]将返回图书数组的前两本书。
-
切片操作:JsonPath支持Python风格的切片操作,允许你访问一个连续的元素序列,而不仅仅是单个元素。例如, $.store.book[1:3]将返回图书数组的第二和第三本书。
-
过滤表达式:JsonPath支持过滤表达式,允许你使用逻辑运算符和比较运算符来过滤返回的元素。例如,$.store.book[?(@.price < 10)]将返回图书数组中价格低于10的所有书。
-
通配符:正如我们前面讨论的,*通配符可以用来匹配任意元素,不论位置。
总的来说,断言是接口测试中的一个重要部分,合理、充分地使用断言,不仅可以提升我们的测试质量,也能帮助我们快速定位问题。同时,塑造良好的断言策略,对于维护和持续提升一个测试框架也是尤为关键的。
最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!凡事要趁早,特别是技术行业,一定要提升技术功底。