python接口自动化知识点

一、接口自动化介绍

1.简介

[接口自动化]是提高测试效率和质量的重要手段之一。

2.为什么要做接口自动化

相对于UI自动化而言,接口自动化具有更大的价值。
为了优化转化路径或者提升用户体验,APP/web界面的按钮控件和布局几乎每个版本都会发生一次变化,导致自动化的代码频繁变更,没有起到减少工作量的效果。
而接口一旦研发完成,后期重构/大幅度修改的频率则比较低.因而做接口自动化性价比还是很高的,对于迭代版本旧有功能的回归,beta测试,线上回归都能起到事半功倍的作用。

3.接口自动化两大类

1、为模拟测试数据而开展的接口自动化
这种接口自动化大多是单次执行,目的很明确是为了功能测试创造测试数据,节约人工造数据的时间和人工成本,提高功能测试人员的测试效率。
2、在功能测试之前提前发现错误而开展的接口自动化
这种接口自动化的工作流程跟功能测试一样,需要设计接口测试用例,然后执行接口测试用例。
说白了就是对单接口进行功能校验,包括接口参数的必填性、长度字符类型限制、入参枚举值等是否正确、响应数据是否正确等进行校验。

4.插件自动安装

1、在项目根目录创建文件:requirements.txt
2、在文件中写入需要安装的插件名

requirements.txt 内容
pytest
requests
pytest-html
pytest-xdist
pytest-ordering
pytest-rerunfailures
pytest-base-url
allure-pytest

二、Requests简介

1.Requests是基于urllib,使用Apache2 许可证开发HTTP库。其在python内置模块的基础上进行了高度封装,使得Requests能够轻松完成浏览器相关的任何操作。
2.接口测试流程

发起请求: 通过HTTP库向目标站点发起请求,等待目标站点服务器响应。

获取响应: 若服务器正常响应,会返回一个Response,该Response
即为获取得页面内容,Response可以是HTML、JSON、字符串、
二进制数据等数据类型。

解析内容:利用正则表达式、网页解析库对HTML进行解析;
将json数据转为JSON对象进行解析;保存我们需要得二进制数据
(图片、视频)。

内容断言:根据解析内容断言期望结果。

3.Requests总览
使用requests发送get请求

以访问百度为例,访问百度时,是使用的get请求,所以这里调
用requests.get()方法,将返回结果用resp接收,这里因为
响应结果是乱码,所以这里把返回结果编码设置为utf-8
import requests

def fun1():
    resp = requests.get("http://www.baidu.com")  #request发送不带参数的get请求
    resp.encoding="utf-8"        #防止中文乱码,设置响应内容编码格式
    print(resp.status_code)      #输出响应状态码
    print(resp.text)            #获取响应的文本信息
 
if  __name__ == "__main__":
    fun1()

#发送get请求带参数--请求格式为字典,使用params参数
以访问百度为例,这里是在百度搜索python,后面增加了一个参数
wd,也可以直接用
resp = requests.get(["](http://www.baidu.com/s """)http://www.baidu.com/s?wd=python"),下面把url和请求参数分别用变量接收

def fun2():
    data_dict={"wd":"python"}
    req_url="http://www.baidu.com/s"
    resp = requests.get(url=req_url,params=data_dict)
    print(resp.status_code)

使用requests发送post请求

post请求的参数分为两种情况,请求头中Content-type是
application/x-www.form-url,后面的参数就是data,
请求头中Content-type是application/json,参数就用json
response = request.post(url,data=None,json=None)
data:参数接收form表单数据,后台会自动附加form表单请求信息头

header={"Content-Type":"application"}

json:参数接收json数据时,后台会自动附加json表单请求信息头

header={“Content-Type”:“application/json”}
data参数提交数据

import requests
url = 'http://httpbin.org/post'

"""带data数据的post"""
data = {'key1':'value1','key2':'value2'}
response = requests.post(url,data=data)
print(response.status_code)
print(response.text)
"""带json数据的post"""
import requests
url_login = "http://ihrm-java.itheima.net/api/sys/login"
#无论表单data还是json,都是用字典发送请求
login_json = {
    "mobile" :"17743533546",
    "password" : "123456"
}
response = requests.post(url=url_login,json=login_json)
#查看响应
print(response.json())

响应公共方法
请求方法的返回值response为Response对象,我们可以从
这个对象中获取所有我们想要的响应信息。

response.status_code 状态码
response.url 请求url
response.encoding 查看响应头部字符编码
response.headers 头信息
response.cookies cookie信息
response.text 文本形式的响应内容
response.content 字节形式的响应内容
response.json() JSON形式的响应内容


import requests
# 1). 访问百度首页的接口`http://www.baidu.com`,获取以下响应数据
response = requests.get("http://www.baidu.com")
# 2). 获取响应状态码
print("响应状态码",response.status_code)
# 3). 获取请求URL
print("请求url",response.url)
# 4). 获取响应字符编码
print("响应字符编码",response.encoding)
# 5). 获取响应头数据
print("响应头数据",response.headers)
#提取响应头数据中某个键的值
print("Content-Type",response.headers.get("Content-Type"))
# 6). 获取响应的cookie数据
print("cookie数据",response.cookies)
print("提取指定的cookie",response.cookies.get("BDORZ"))
# 7). 获取文本形式的响应内容
print("文本形式内容",response.text)
# 8). 获取字节形式的响应内容
print("响应内容",response.content)

其他

如果需要为请求添加请求头数据,只需要传递一个字典类型的
数据给 headers 参数就可以了

"""
1. 请求IHRM项目的登录接口,URL: http://ihrm-java.itheima.net/api/sys/login
2. 请求头: Content-Type: application/json
3. 请求体: {"mobile":"17743533546", "password":"123456"}
"""
#设置请求头
import requests
url_login = "http://ihrm-java.itheima.net/api/sys/login"
#请求头是一个键值对
header  = {
    "Content-Type":"application/json"
}
login_data = {
    "mobile":"17743533546",
    "password":"123456"
}
response = requests.post(url=url_login,json=login_data,headers=header)
response.encoding = 'utf-8'
print(response.json())

"""下载图片"""
import requests
import matplotlib.pyplot as plt

url = 'https://cn.bing.com/images/search?view=detailV2&ccid=qr8JYj0b&id=6CEE679B0BCE19C94FB9C7595986720942C92261&thid=OIP.qr8JYj0bcms3xayruiZmnAHaJQ&mediaurl=https%3a%2f%2ftse1-mm.cn.bing.net%2fth%2fid%2fR-C.aabf09623d1b726b37c5acabba26669c%3frik%3dYSLJQglyhllZxw%26riu%3dhttp%253a%252f%252fp1.ifengimg.com%252f2019_02%252f95A41E54C3C8EB3B3B148A30CE716314B0AED504_w1024_h1280.jpg%26ehk%3d2EhKcVkSnCvT6uBfgisn%252fdwtghMXFWjGa5WgqEbBSPc%253d%26risl%3d%26pid%3dImgRaw&exph=1280&expw=1024&q=%e7%9f%b3%e5%8e%9f%e9%87%8c%e7%be%8e&simid=607996751665040666&FORM=IRPRST&ck=399D74E04F8507D6711ADC8F53A714D7&selectedIndex=0&ajaxhist=0&ajaxserp=0'
response = requests.get(url)
img = response.content

with open('shiyuanlimei.jpg','wb') as f:
    f.write(img)


"""接口参数关联请求"""
datas = {
        "username":"qcj",
        "password":"123456"
    }
login_url = "http://www.fanyunedu.com:5000/general/login_token"
rep = requests.post(url=login_url,data = datas)
req_json = rep.json()
token =req_json['data']
headers = {
        "auth-token":token
}
t_url="http://www.fanyunedu.com:5000/general/userinfo_token"
t_req = requests.get(url=t_url,headers=headers)



"""加密接口请求"""
    uid,name,password,salt='3','qcj','123456','LZ7dYxCj5S68ucAh'
    import hashlib
    hl = hashlib.md5()
    hl.update('{}-{}-{}-{}'.format(uid,name,password,salt).encode('utf-8'))
    sigh = hl.hexdigest()#对hl对象中保存的字段进行md5的加密算法
    datas={"uid":"3","sign":sigh}
    url_data = "http://www.fanyunedu.com:5000/general/userinfo_sign"
    req = requests.post(url=url_data,json=datas)

三、Yaml知识点

1.Yaml简介
YAML 是一种可读性非常高,与程序语言数据结构非常接近。同时具备丰富的表达能力和可扩展性,并且易于使用的数据标记语言。
其实YAML文件也是一种配置文件,但是相较于ini,conf配置文件来说,更加的简洁,操作简单,还能存放不同类型的数据;而像ini存储的值就都是字符串类型,读取之后还要手动转换
2.YAML的基本语法规则
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。(可以将你的ide的tab按键输出替换成4个空格)
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

表示注释

3.YAML支持的数据结构
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
4.YAML,对象数据类型
对象的一组键值对,使用冒号结构表示。

animal: dogs

转换成Python数据结构,如下:

{'animal': 'dogs'}

将所有键值对赋值。

hash: { name: Steve, foo: bar }

转换成Python数据结构,如下:

{'hash': {'name': 'Steve', 'foo': 'bar'}}

将列表赋值

lists : [1,2,3]

转换成Python数据结构,如下:

{'lists': [1, 2, 3]}

将元组赋值

tuples : (1,2,3)

转换成Python数据结构,如下:

{'tuples': '(1,2,3)'}

总结
当赋值列表、键值对时,转换成Python数据结构是可以直接当列表、字典使用的;
当赋值元组时,转换后也是字符串
最终输出的都是字典类型,可以通过key获取对应的值
以 - 开头的行表示构成一个数组

四、python+requests+pytest+yaml+allure接口自动化框架

四.框架的介绍:

1.common层构建基础类库:为了提高测试用例的可维护性性和复用性,其中包括日志输出,接口统一发送请求,yaml文件的读取,
写入,清除的方法
2.data层:存放测试用例yaml数据
3.logs层:存放日志
4.reports层:存放生成的allure报告
5.temps层:存放生成的临时报告
6.testcase层:测试用例
7.pytest.ini:配置文件
8.requirements.txt:依赖包
9.run.py:自动化框架运行脚本的文件,然后会在reports生成allure报告
框架的使用说明:
1.环境配置:需要在pycharm终端里安装requirements.txt依赖包,输入pip install -requirements.txt部署环境
2.编写测试用例数据是用yaml文件进行传参,其中包含测试所有API的参数,这个文件可以包括
接口名称(name),请求(request),请求方法(menthod),请求路径(URL),请求参数(params)
举例:

3.测试用例以test_XXX命名,XXX是测试用例的名字,其中包括allure标记的装饰器,数据驱动,断言,
@allure.story(),allure.dynamic.title()是allure标记的装饰器
@pytest.mark.parametrize("caseinfo", read_testcase("./data/test_get_token.yaml"))
这行代码使用了pytest框架提供的 @pytest.mark.parametrize()装饰器,具体含义是read_testcase()yaml文件
读取的函数从路径"./data/test_get_token.yaml"文件中读取到测试用例数据集作为参数,将其命名为caseinfo,并
传递给被装饰器的测试函数.
test_get_token()的测试函数,该函数使用了参数化方式运行多组测试用例,每组测试用例都是一个字典函数,包含了请求参数
和预期结果信息,用yaml数据格式进行value:key方式进行传参.
断言用是pytest自带的断言方式assert

举例:
@pytest.mark.parametrize("caseinfo", read_testcase("./data/test_get_token.yaml"))
@allure.story("获取token接口")
def test_get_token(self, caseinfo):
allure.dynamic.title("获取token")
method = caseinfo["request"]["method"]
url = caseinfo["request"]["url"]
params = caseinfo["request"]["params"]
res = RequestUntil().send_request(method=method, url=url, params=params)
print(res.json()["access_token"])
write_yaml(res.json()["access_token"])
assert res.status_code== 200
assert "access_token" in res.text
4.执行测试
点击run.py文件.执行脚本,然后会在reports包里生成一份allure报告,点击idex.html,点击浏览器就可以查看
本地allure报告

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容