<article data-content="[{"type":"block","id":"3060-1621846615933","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"p5PQ-1621846617594","leaves":[{"text":"第15讲 python + requests接口自动化测试","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"R7XH-1657365743449","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"3eHB-1657365743057","leaves":[{"text":"1、开发提供接口文档(如果没有接口文档,那就用fiddler或者f12抓包)","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"XmAO-1657365743450","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"7K83-1657365743059","leaves":[{"text":"2、接口测试的定义","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"HCF6-1657365743451","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"M5Vw-1657365743061","leaves":[{"text":"接口测试时针对系统于组件之间,或者模块于模块之间数据交互,传递,逻辑 依赖关系","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"JHGh-1657365743452","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"eevH-1657365743063","leaves":[{"text":"3、接口自动化测试定义","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"yqcq-1657365743453","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"Wfqv-1657365743065","leaves":[{"text":"通过自动化工具,编写代码实现对接口批量运行的测试","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"Y94W-1657365743454","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"Zi4n-1657365743068","leaves":[{"text":"4、接口自动化测试的优点","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"QVBv-1657365743455","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"hzje-1657365743070","leaves":[{"text":"相比ui自动化测试,接口自动化测试收益更大,容易实现,维护成本比较低,接口比较重要","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"zUOb-1657365743456","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"yWU3-1657365743072","leaves":[{"text":"5、接口自动化测试的流程","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"Osd5-1657365743457","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"HifI-1657365743074","leaves":[{"text":"需求分析==》需求评审==》接口自动化测试计划==》设计接口用例==》脚本开发==》执行脚本==》结果分析","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"GLeZ-1657365743458","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"kc6y-1657365743076","leaves":[{"text":"6、接口自动化测试会达到什么效果","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"zqo6-1657365743459","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"Y3FA-1657365743078","leaves":[{"text":"1)提高效率,提高回归测试,场景覆盖 代码核查效率","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"Ml98-1657365743460","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"7wnF-1657365743080","leaves":[{"text":"2)解决在页面操作构造数据比较复杂时,可以用接口来实现","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"Y8j2-1657365743461","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"cOCD-1657365743083","leaves":[{"text":"7、安装requests库","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"1BW0-1657365743462","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"3K9k-1657365743085","leaves":[{"text":"在dos窗口输入cmd ==》输入pip install requests ==》安装完后在C:\\Python37\\Lib\\site-packages查看","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"gEgu-1657365743463","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"EYhh-1657365743087","leaves":[{"text":"8、python 中常用作接口自动化的库又哪些?","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"G4bo-1657365743464","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"1rec-1657365743089","leaves":[{"text":"requests urllib urllib3 httplib","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"0cAp-1657365743465","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"DJO0-1657365743091","leaves":[{"text":"9、创建接口请求的3种方式?【重要】","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"63Kc-1657365743466","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"mvoM-1657365743093","leaves":[{"text":"import requests #导入requests库","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"zlQA-1657365743467","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"0PKe-1657365743095","leaves":[{"text":"res = requests.post(url=" url',data="data" ,json="json" )","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"oj30-1657365743468","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"vbtm-1657365743097","leaves":[{"text":"res="requests.request('post',data" =="" 'data',url="url" ,)","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"mdkb-1657365743469","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"pm7z-1657365743099","leaves":[{"text":"res="requests.Session()" #保持上下文一直,在一个会话里面","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"utst-1657365743470","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"wp5c-1657365743101","leaves":[{"text":"10、get和post请求参数位置【重要】","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"my3v-1657365743471","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"prfy-1657365743103","leaves":[{"text":"get="" 请求一般参数放在params里面","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"4uk6-1657365743472","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"mtux-1657365743105","leaves":[{"text":"post请求一般放在data或者json里面,如果content-type="" 是application="" x-www-form-urlencode","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"nbvb-1657365743473","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"tpla-1657365743107","leaves":[{"text":"类型是data,如果是application="" json="" 类型则是json","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"fuwm-1657365743474","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"18lz-1657365743109","leaves":[{"text":"import="" requests","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"83di-1657365743475","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"eiwq-1657365743112","leaves":[{"text":"11、组建一个post请求【重要】","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"iogi-1657365743476","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"zlxg-1657365743114","leaves":[{"text":"发一个接口请求基本组成有哪些?","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"ulxo-1657365743477","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"ebez-1657365743116","leaves":[{"text":"url地址="" 入参信息="" headers="" 接口请求方式","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"j2ro-1657365743478","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"depf-1657365743119","leaves":[{"text":"1)定义一个url","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"dljz-1657365743479","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"daa6-1657365742612","leaves":[{"text":"login_url="","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]},{"type":"inline","id":"TPwy-1657365742614","name":"link","data":{"href":"http://cms.duoceshi.cn/cms/manage/loginJump.do"},"nodes":[{"type":"text","id":"XT8u-1657365742613","leaves":[{"text":"http://cms.duoceshi.cn/cms/manage/loginJump.do","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"text","id":"uAoP-1657365742625","leaves":[{"text":"" ","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"fik3-1657365743480","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"gsqw-1657365743122","leaves":[{"text":"#="" 2)登录参数","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"qanu-1657365743481","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"y4sv-1657365743124","leaves":[{"text":"login_data="{'userAccount':'admin','loginPwd':123456}","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"VtVY-1657365743482","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"GwVc-1657365743126","leaves":[{"text":"#" 3)请求头信息","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"b3cc-1657365743483","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"xbyz-1657365743128","leaves":[{"text":"login_headers="{'Content-Type':'application/x-www-form-urlencoded'}","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"wQs0-1657365743484","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"S8H4-1657365743130","leaves":[{"text":"res" requests.post(url="login_url,data=login_data,headers=login_headers)","marks":[{"type":"bold"},{"type":"fontSize","value":26}]}]}]},{"type":"block","id":"QKMb-1657365743485","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"Vd3k-1657365743132","leaves":[{"text":"result=" res.text="" #拿到响应结果","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"da2m-1657365743486","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"fxub-1657365743134","leaves":[{"text":"print(result)="" #{\"code\":\"200\",\"msg\":\"登录成功!\",\"model\":{}}","marks":[{"type":"bold"},{"type":"fontsize","value":26}]}]}]},{"type":"block","id":"qqjr-1657365743487","name":"heading","data":{"version":1,"level":"h1"},"nodes":[{"type":"text","id":"sgw6-1657365743136","leaves":[{"text":"print(type(result))="" #
第15讲 python + requests接口自动化测试
1、开发提供接口文档(如果没有接口文档,那就用fiddler或者f12抓包)
2、接口测试的定义
接口测试时针对系统于组件之间,或者模块于模块之间数据交互,传递,逻辑 依赖关系
3、接口自动化测试定义
通过自动化工具,编写代码实现对接口批量运行的测试
4、接口自动化测试的优点
相比ui自动化测试,接口自动化测试收益更大,容易实现,维护成本比较低,接口比较重要
5、接口自动化测试的流程
需求分析==》需求评审==》接口自动化测试计划==》设计接口用例==》脚本开发==》执行脚本==》结果分析
6、接口自动化测试会达到什么效果
1)提高效率,提高回归测试,场景覆盖 代码核查效率
2)解决在页面操作构造数据比较复杂时,可以用接口来实现
7、安装requests库
在dos窗口输入cmd ==》输入pip install requests ==》安装完后在C:\Python37\Lib\site-packages查看
8、python 中常用作接口自动化的库又哪些?
requests urllib urllib3 httplib
9、创建接口请求的3种方式?【重要】
import requests #导入requests库
res = requests.post(url='url',data = 'data',json='json')
res = requests.request('post',data = 'data',url='url',)
res = requests.Session() #保持上下文一直,在一个会话里面
10、get和post请求参数位置【重要】
get 请求一般参数放在params里面
post请求一般放在data或者json里面,如果content-type 是application/x-www-form-urlencode
类型是data,如果是application/json 类型则是json
import requests
11、组建一个post请求【重要】
发一个接口请求基本组成有哪些?
url地址 入参信息 headers 接口请求方式
1)定义一个url
login_url = 'http://cms.duoceshi.cn/cms/manage/loginJump.do'
# 2)登录参数
login_data ={'userAccount':'admin','loginPwd':123456}
# 3)请求头信息
login_headers = {'Content-Type':'application/x-www-form-urlencoded'}
res = requests.post(url=login_url,data=login_data,headers=login_headers)
result= res.text #拿到响应结果
print(result) #{"code":"200","msg":"登录成功!","model":{}}
print(type(result)) # 字符串格式
print(res.headers) #拿到响应头
s = res.json() #把接口返回的json字符串通过json函数转化为字典格式
print(s) #{'code': '200', 'msg': '登录成功!', 'model': {}}
print(type(s)) # 字典格式
print(res.cookies) #拿到cookies值
print(res.status_code) #拿到状态码
print(res.encoding) #拿到编码格式
#第一种断言方法
if s['msg']=='登录成功!':
print('接口联调成功')
else:
print('接口联调失败')
#第二种断言方法
assert s['msg']=='登录成功!'
12、组建get请求
发送一个get请求的的基本组成有哪些?
url 地址 参数 接口请求方法
1)定义一个url
login_url = 'http://cms.duoceshi.cn/cms/manage/loginJump.do'
# 2)登录参数
login_params={'userAccount':'admin','loginPwd':123456}
res = requests.get(url=login_url,params=login_params)
r = res.text
print(r) #{"code":"200","msg":"登录成功!","model":{}}
print(type(r)) #
13、封装在类里面
import requests
class Cms:
def init(self):
#创建一个session对象,作用保持上下文的管理,使登录之后的接口和登录接口保持在
# 一个会话里面
self.session = requests.Session()
def login(self):
login_url = 'http://cms.duoceshi.cn/cms/manage/loginJump.do'
login_data = {'userAccount': 'admin', 'loginPwd': 123456}
login_headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = self.session.post(url=login_url,data=login_data,headers=login_headers)
r = res.text
print(r)
def queryUserList(self):
url='http://cms.duoceshi.cn/cms/manage/queryUserList.do'
data = {'startCreateDate':'','endCreateDate':'','searchValue':'',
'page':1}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = self.session.post(url=url,data=data,headers=headers)
r = res.text
print(r)
if name == 'main':
c = Cms()
c.login()
c.queryUserList()
14 把上面的代码进行优化,用unittest框架进行管理
import unittest
import requests
class Cms_Test(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None: #类方法的开始
cls.session = requests.Session() #创建一个session对象作为类的一个属性
def setUp(self) -> None: #方法的开始
print('...start...')
def tearDown(self) -> None: #方法的结束
print( '...end...')
def test01_login(self):
'''封装一个登录方法'''
login_url = 'http://cms.duoceshi.cn/cms/manage/loginJump.do'
login_data = {'userAccount': 'admin', 'loginPwd': 123456}
login_headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = self.session.post(url=login_url,data=login_data,headers=login_headers)
r = res.json()
print(r)
def test02_queryUserLis(self):
url='http://cms.duoceshi.cn/cms/manage/queryUserList.do'
data = {'startCreateDate':'','endCreateDate':'','searchValue':'',
'page':1}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = self.session.post(url=url,data=data,headers=headers)
r = res.json()
print(r)
if name == 'main':
unittest.main()
#作业
把剩下4条用例用unittest编写完,然后生成报告
15 关联接口1
关联接口的定义:上一个接口的返回值作为下一个接口的入参
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportProvince ==》省份接口
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportCity
==》城市接口
import requests
import re
class Provice:
def get_provice(self):
'''封装要给获取省份接口'''
url = 'http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportProvince'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = requests.post(url=url,headers=headers)
r = res.text
all = re.findall('(.+)',r)
return all #把返回的省份值给回函数调用处,谁调了这个函数谁就拿到了这个值,
#all 使一个列表里面的值需要作为下一个接口入参
def get_city(self,index):
url = 'http://www.webxml.com.cn/WebServices/WeatherWebService.asmx/getSupportCity'
data = {'byProvinceName':self.get_provice()[index]} #self.get_provice()=all
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
res = requests.post(url = url,data=data,headers=headers)
r = res.text
print(r)
if name == 'main':
p = Provice()
p.get_provice()
p.get_city(6)
关联接口二【重要】
获取uuid
http://manage.duoceshi.com/auth/code
登录
http://manage.duoceshi.com/auth/login
{"username":"admin","password":"wYbwqxQk5+yEeC95YwzGtq6huWntl80i7AuF1OcmMkh0xYhwGcRg8+Ik99COTLsmh/FO1RZzDXzPjAH3hEDhOQ==","code":"8888","uuid":"${uuid}"
}
商品分类接口
http://manage.duoceshi.com/api/yxStoreCategory?page=0&size=10&sort=sort%2Cdesc
import requests
class Test(object):
'''获取uuid'''
def code(self):
url = 'http://manage.duoceshi.com/auth/code'
res = requests.get(url=url) #调用接口返回hui响应
r = res.json() #获取的响应转化为json格式(字典格式)
self.uuid = r['uuid'] #字典通过uuid这个键拿到uuid的值
# print(r)
# print(self.uuid)
def login(self):
url = 'http://manage.duoceshi.com/auth/login'
json = {"username":"admin","password":"wYbwqxQk5+yEeC95YwzGtq6huWntl80i7AuF1OcmMkh0xYhwGcRg8+Ik99COTLsmh/FO1RZzDXzPjAH3hEDhOQ==",
"code":"8888","uuid":self.uuid}
headers = {'Content-Type': 'application/json'}
res = requests.post(url=url,json=json,headers=headers)
r = res.json() #获取的响应转化为json格式(字典格式)
self.token = r['token'] #字典通过token这个键拿到token的值
# print(r)
# print(self.token)
def select_goods(self): url = 'http://manage.duoceshi.com/api/yxStoreCategory?page=0&size=10&sort=sort%2Cdesc' headers = {'Authorization': self.token} res = requests.get(url=url,headers=headers) r = res.text print(r)
if name == 'main':
t = Test()
t.code()
t.login()
t.select_goods()
|
|