首页 > 其他 > 详细

接口自动化-requests

时间:2020-12-07 09:43:23      阅读:34      评论:0      收藏:0      [点我收藏+]

一、requests搭建框架的特点

https://requests.readthedocs.io/en/master/

>>> r = requests.get(https://api.github.com/user, auth=(user, pass))
>>> r.status_code
200
>>> r.headers[content-type]
application/json; charset=utf8
>>> r.encoding
utf-8
>>> r.text
{"type":"User"...
>>> r.json()
{private_gists: 419, total_private_repos: 77, ...}
  • 功能全面:http/https支持全面
  • 使用简单:简单易用,不用关心底层细节
  • 定制性搞:借助于hook机制完成通用处理

常见http方法请求构造

r = requests.get(‘https://api.github.com/events‘)
r = requests.post(‘https://httpbin.org/post‘, data = {‘key‘:‘value‘})
r = requests.put(‘https://httpbin.org/put‘, data = {‘key‘:‘value‘})
r = requests.delete(‘https://httpbin.org/delete‘)
r = requests.head(‘https://httpbin.org/get‘)
r = requests.options(‘https://httpbin.org/get‘)

一个小的接口测试用例

import requests

class TestDemo:
    def test_demo(self):
        r=requests.get(http://http.xxx.com/get)
        status=r.status_code
        assert status == 200

二、接口请求构造

  • get query: path、query
  • post body:
    •   form:
    •        结构化请求:json,xml,json rpc
    •        binary (文件上传)

get query实例

payload = {key1: value1, key2: value2}
r = requests.get(https://httpbin.org/get, params=payload)#get用的是params, 返回结果是在arg里
print(r.url)
#https://httpbin.org/get?key2=value2&key1=value1
print(r.text)
##response
"args": {
‘key1‘: ‘value1‘,
‘key2‘: ‘value2‘
},

post 请求实例

payload = {key1: value1, key2: value2}
r = requests.post("https://httpbin.org/post", data=payload)#post是用data=,response在form中显示。
print(r.text)

{
  ...
  "form": {
    "key2": "value2",
    "key1": "value1"
  },
  ...
}

文件上传(binary)

#文件上传
  def test_file(self):
        files={file:open(report.xls,rb)}#文件以rb模式读取
        url=‘‘
        r=requests.post(url,files=files)

#把响应的binary data转换成图片(如果是图片的话)
For example, to create an image from binary data returned by a request, you can use the following code:

>>> from PIL import Image
>>> from io import BytesIO

>>> i = Image.open(BytesIO(r.content))  

headers构造

>>> url = https://api.github.com/some/endpoint
>>> headers = {user-agent: my-app/0.0.1}

>>> r = requests.get(url, headers=headers)

cookies

##If a response contains some Cookies, you can quickly access them:
>>> url = http://example.com/some/cookie/setting/url
>>> r = requests.get(url)

>>> r.cookies[example_cookie_name]
example_cookie_value

##To send your own cookies to the server, you can use the cookies parameter:
>>> url = https://httpbin.org/cookies
>>> cookies = dict(cookies_are=working)

>>> r = requests.get(url, cookies=cookies)
>>> r.text
{"cookies": {"cookies_are": "working"}}

 

三、结构化请求体构造json xml
大部分接口请求和响应都是以结构化的形式展现的,主要是json
json实例
#There are times that you may want to send data that is not form-encoded. If you pass in a string instead of a dict, that data will be posted directly.

#For example, the GitHub API v3 accepts JSON-Encoded POST/PATCH data:

>>> import json

>>> url = https://api.github.com/some/endpoint
>>> payload = {some: data}

>>> r = requests.post(url, data=json.dumps(payload))#字典转换成string

#Instead of encoding the dict yourself, you can also pass it directly using the json parameter (added in version 2.4.2) and it will be encoded automatically:

>>> url = https://api.github.com/some/endpoint
>>> payload = {some: data}

>>> r = requests.post(url, json=payload)
#Note, the json parameter is ignored if either data or files is passed.

#Using the json parameter in the request will change the Content-Type in the header to application/json.

xml实例

xml不常用,data=xml,requests里没有封装xml,所以不能像json那样直接写入,需要在headers里要追加application/xml,

        url = https://api.github.com/some/endpoint
        xml=‘‘
        headers = {Content-Type: application/xml}
        r=requests.post(url,data=xml,headers=headers).text

复杂数据结构请求:

将数据存入文件,用工具(mustache,freemaker)解析

  • 数据保存:将复杂的xml或者json请求体保存文件模板中
  • 数据处理:
    •   使用mustache,freemaker等工具解析
    •        简单的字符串替换
    •        使用json xml api进行结构化解析
  • 数据生成:输出最终结果
    #用两个花括号识别变量,可以对变量进行自动识别和替换
    import pystache
    j=pystache.render(‘Hi {{person}}‘, {"person":"Lucky"})#第一个参数是str,后面是要改变的变量 print(j)

     

四、响应断言

  • 基本信息:r.url, r.status_code, r.headers, r.cookies
  • 响应结果:
    •   r.text=r.encoding+r.content
    •        r.json()=r.encoding+r.content+content type json
    •        r.raw.read(10)
  • 对应的请求内容:r.request

def test_heads(self):

r=requests.get(‘http://httpbin.com/get‘,headers={"h":"head demo"})

head=r.json()["headers"]["H"]

assert head=="head demo"

五、json、xml响应断言

除了可以用字典key value的形式获取json内某个value的值,

也可以用json path,类似于xpath 去写,这样可以处理更加复杂的json结构体,jsonpath要导入

参考:https://www.cnblogs.com/k5210202/p/13079738.html

语法

xpath对比示例

XPath JSONPath Result
/store/book/author $.store.book[*].author the authors of all books in the store
//author $..author all authors
/store/* $.store.* all things in store, which are some books and a red bicycle.
/store//price $.store..price the price of everything in the store.
//book[3] $..book[2] the third book
//book[last()] $..book[(@.length-1)]
$..book[-1:]
the last book in order.
//book[position()<3] $..book[0,1]
$..book[:2]
the first two books
//book[isbn] $..book[?(@.isbn)] filter all books with isbn number
//book[price<10] $..book[?(@.price<10)] filter all books cheapier than 10
//* $..* all Elements in XML document. All members of JSON structure.

json 断言实例

from jsonpath import jsonpath
def test_json(self):
r=requests.get("https://ceshiren.com/categories.json")
#name=r.json()[‘category_list‘][‘categories‘][0][‘name‘]#字典key value形式
name=jsonpath(r.json(),$..name)[0]#jsonpath传入的内容必须是json obj
print(name)
assert name == 开源项目

xml 断言实例

因为requests没有对xml的封装,可以使用第三方库,requests_xml 就可以实现像json那样的导入了
https://www.ctolib.com/erinxocon-requests-xml.html
def test_xml(self):
        session = XMLSession()
        r = session.get(https://www.nasa.gov/rss/dyn/lg_image_of_the_day.rss)
        print(r.xml.links)
       #XPath is the main supported way to query an element (learn more):
        print(r.xml.xpath(//item, first=True))#取item的文字可以是r.xml.xpath(‘//item‘, first=True).text

#[‘http://www.nasa.gov/image-feature/from-the-earth-moon-and-beyond‘, ‘http://www.nasa.gov/image-feature/jpl/pia21974/jupiter-s-colorful-cloud-belts‘, ‘http://www.nasa.gov/‘, ‘http://www.nasa.gov/image-feature/portrait-of-the-expedition-54-crew-on-the-space-station‘, ...] 
#
<Element ‘item‘ >
xml语言可以用xml.etree.ElementTree来解析
find是找子节点  
rank = country.find(‘rank‘).text
get
country.get(‘name‘)
 
attrib
for child in root:
...     print child.tag, child.attrib
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
 
import xml.etree.ElementTree as ET
tree = ET.parse(country_data.xml)#xml存在文件
#root = ET.fromstring(country_data_as_string)#直接从string中导入
root = tree.getroot()

>>> for child in root:
...     print child.tag, child.attrib
...
country {name: Liechtenstein}
country {name: Singapore}
country {name: Panama}

Element has some useful methods that help iterate recursively over all the sub-tree below it (its children, their children, and so on). For example, Element.iter():

>>> for neighbor in root.iter(neighbor):
...     print neighbor.attrib
...
{name: Austria, direction: E}
{name: Switzerland, direction: W}
{name: Malaysia, direction: N}
{name: Costa Rica, direction: W}
{name: Colombia, direction: E}

Element.findall() finds only elements with a tag which are direct children of the current element. Element.find() finds the first child with a particular tag, and Element.text accesses the element’s text content. Element.get() accesses the element’s attributes:

>>> for country in root.findall(country):
...     rank = country.find(rank).text
...     name = country.get(name)
...     print name, rank
...
Liechtenstein 1
Singapore 4
Panama 68
###################
This module provides limited support for XPath expressions for locating elements in a tree. The goal is to support a small subset of the abbreviated syntax; a full XPath engine is outside the scope of the module.

import xml.etree.ElementTree as ET

root = ET.fromstring(countrydata)

# Top-level elements,<data></data> 输出是Element data...
root.findall(".") # All ‘neighbor‘ grand-children of ‘country‘ children of the top-level # elements root.findall("./country/neighbor") # Nodes with name=‘Singapore‘ that have a ‘year‘ child root.findall(".//year/..[@name=‘Singapore‘]") # ‘year‘ nodes that are children of nodes with name=‘Singapore‘ root.findall(".//*[@name=‘Singapore‘]/year") # All ‘neighbor‘ nodes that are the second child of their parent root.findall(".//neighbor[2]")

 

def test_heads(self):
    r=requests.get(http://httpbin.testing-studio.com/get,headers={"h":"head demo"})
    head=r.json()["headers"]["H"]
    assert head=="head demo"
遇到的坑:get没有加上,报错JSONDecodeError("Expecting value", s, err.value) from None
接口测试报错,首先要检查请求是否是对的

 

 

 

接口自动化-requests

原文:https://www.cnblogs.com/hurgry-coding/p/14094016.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!