简单来说,接口测试其实就是功能测试,都是根据具体业务需求进行测试并以发现bug为目的。
所谓接口自动化测试,也就是根据接口文档和业务需求去设计接口测试用例,并通过编写自动化脚本去执行接口测试用例,进而发现接口中存在的bug。
接口测试可以发现软件开发初期的bug,维护成本低而且效率高,所以做接口测试是很有必要的。
本文将记录如何使用Python+Yaml来实现接口自动化测试脚本的编写,以天气API中的实况天气查询接口为例,地址:http://www.tianqiapi.com/index/doc?version=day
一、基本业务
实况天气查询:可实时查看城市天气,包含基本天气、温度、风力风向、空气质量指数等指标,可按地名、城市编号、IP进行查询。
根据业务需求,使用Excel编写了几条接口测试用例,如下图
四、编写自动化脚本
请求接口:在业务层com下新建Weather.py文件,创建一个Weather类,并在类中创建一个实况天气查询方法
注:
1.需安装requests库,用来发送请求,安装方法:打开cmd,输入:pip install requests
2.可安装pprint库,用来美化输出响应结果,安装方法:打开cmd,输入:pip install pprint
,pprint与print输出对比效果如下
创建yaml测试用例:在数据层data下新建WeatherCase.yaml文件,用来存放yaml格式的接口测试用例,根据Excel用例进行拆分
Yaml基本语法:
1.大小写敏感;
2.使用缩进表示层级关系;
3.缩进时不允许使用Tab键,只允许使用空格键;
4.缩进的空格数目不重要,只要相同层级的元素左对齐即可;
5.#表示注释,从它开始到行尾都被注释;
6.字符串可以不用引号标注;
注:虽然yaml语法对于字符串可以不用引号标注,如果接口中返回的数据类型为字符串时,
则yaml上用于断言的数字建议使用引号标注,免得在断言时因为数据类型不同,而使测试用例执行失败。
如本接口返回的cityid数据类型为“str”,而用例上的cityid如果不用引号标注,则类型为"int",即使值一样也会判断不通过。
读取yaml用例:在工具层tools下新建yamlContorl.py文件,用来读取yaml测试用例
注:需安装PyYaml库,安装方法:打开cmd,输入: pip install pyyaml
执行测试:在执行层test_case下新建test_Weather.py文件,执行所有测试用例
注:在断言时,如果同一个返回字段不是必然出现时,则需要判断其是否存在,若不存在,则需要换一个字段进行断言。如本接口在errcode=100时,是不返回city和cityid字段的,因此要根据实际返回的errcode和errmsg字段去设置断言。
五、测试结果
附代码
# Weather.py
import requests
import pprint
from configs.tianqiAPI import HOST
class Weather():
def WeatherQuery(self, inData): # 实况天气查询
# 请求地址
url = HOST + "/free/day"
# 请求参数
payload = inData
# 请求
res = requests.get(url, payload)
return res.json() # 返回字典格式的响应数据
if __name__ == '__main__': # 快捷键:输入main,然后按回车键
param = {"appid": "47242322", "appsecret": "4cUoG0rk", "city": "广州"}
resp = Weather().WeatherQuery(param)
pprint.pprint(resp)
# WeatherCase.yaml
- # 接口路径及请求方式
url: /free/day
method: GET
- # 用例编号:test_001
detail: 传正确的账号、密码 # 用例名称
data: # 请求参数
appid: 47242322
appsecret: 4cUoG0rk
city: 广州
resp: # 预期响应结果
city: 广州
cityid: '101280101'
- # 用例编号:test_002
detail: 传未注册的账号
data:
appid: dgsd1
appsecret: 4cUoG0rk
city: 广州
resp:
errcode: 100
errmsg: appid错误!
- # 用例编号:test_003
detail: 传正确的账号但密码错误
data:
appid: 47242322
appsecret: 1111111
city: 广州
resp:
errcode: 100
errmsg: appsecret错误!
- # 用例编号:test_004
detail: 账号密码传入空值
data:
appid: ""
appsecret: ""
city: 广州
resp:
errcode: 100
errmsg: 缺少注册参数appid或appsecret 请仔细看文档 https://tianqiapi.com/
- # 用例编号:test_005
detail: 传入带后缀的城市名(如广州市、天河区)
data:
appid: 47242322
appsecret: 4cUoG0rk
city: 广州市
resp:
city: 北京
cityid: '101010100'
# yamlContorl.py
import yaml
def get_yaml_data(fileDir):
# 读取文件操作---从磁盘读取到内存
fo = open(fileDir, 'r', encoding='utf-8')
# 使用yaml方法读取数据
res = yaml.load(fo, Loader=yaml.FullLoader) # 全局加载,res为一个列表
fo.close()
del res[0] # 删除yaml用例中的第一组数据(存放url和method的那组),只用来存放用例
return res
if __name__ == '__main__':
results = get_yaml_data("../data/WeatherCase.yaml")
for one in results:
print(one)
# test_Weather.py
# 执行用例
import pprint
from com.Weather import Weather
from tools.yamlContorl import get_yaml_data
# 1- 获取用例数据
res = get_yaml_data("../data/WeatherCase.yaml")
for one in res:
print("用例【"+one['detail']+"】开始执行!")
# 2- 调用接口方法---获取响应数据
respData = Weather().WeatherQuery(one['data'])
# pprint.pprint(respData)
# 3- 断言
if 'cityid' in respData:
if respData['cityid'] == one['resp']['cityid']:
print("---用例通过---")
else:
print("---用例失败---")
else:
if respData['errcode'] == one['resp']['errcode'] and respData['errmsg'] == one['resp']['errmsg']:
print("---用例通过---")
else:
print("---用例失败---")