接口测试库requests 及常用断言库

我们在测试接口的过程中  对于接口返回的常用格式 有 json和html xml等; 常用的场景需要我们对返回的数据进行处理, 比如对返回数据的校验断言等操作.

插件一:json文件解析库jsonpath

官方文档: https://goessner.net/articles/JsonPath/

使用场景:

curl命令请求返回的json数据可以用 | jq 来格式化成json数据

结合  grep 查找关键字来查找元素值  | jq '.' | grep name

可以通过json树来定位元素 | jq -r '.data.stocks[0].name'

适用于复杂的断言:

列表中的元素是字典 字典中的值sybol==F006947时 name值是不是等于"华宝中短债债券A"

assert jsonpath.jsonpath(r.json(),
"$.data.stocks[?(@.symbol == 'F006947')].name")[0]=="华宝中短债债券A"
assert_that(jsonpath.jsonpath(r.json(),"$.data.stocks[?(@.symbol == 'F006947')].name")[0],
equal_to("华宝中短债债券B"), "比较上市代码与名字")
{ "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", "isbn": "0-553-21311-3", "price": 8.99 }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 } ], "bicycle": { "color": "red", "price": 19.95 } } }
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.

插件二:HTML文本解析库BeautifulSoup 、  css selector + xpath  

参考文献:https://foofish.net/crawler-beautifulsoup.html

BeatifulSoup 是一个用于操作 HTML 文档的 Python 库,初始化 BeatifulSoup 时,需要指定 HTML 文档字符串和具体的解析器。BeatifulSoup 有3类常用的数据类型,分别是 Tag、NavigableString、和 BeautifulSoup。查找 HTML元素有两种方式,分别是遍历文档树和搜索文档树,通常快速获取数据需要二者结合。通过 BeautifulSoup 对象就可以定位到 HTML 中的任何一个标签节点。

from bs4 import BeautifulSoup  
text = """ <html>  <head>  <title >hello, world</title>  </head>  <body>  <h1>BeautifulSoup</h1>  <p class="bold">如何使用BeautifulSoup</p>  <p class="big" id="key1"> 第二个p标签</p>  <a href="http://foofish.net">python</a>  </body> </html> """ soup = BeautifulSoup(text, "html.parser") # title 标签 >>> soup.title <title>hello, world</title> # p 标签 >>> soup.p <p class="bold">\u5982\u4f55\u4f7f\u7528BeautifulSoup</p> # p 标签的内容 >>> soup.p.string u'\u5982\u4f55\u4f7f\u7528BeautifulSoup'

插件三:xml解析库Xpath

插件四:text解析库 regex

插件五:断言库hamcrest

官方文档: https://github.com/hamcrest/PyHamcrest

from hamcrest import *
import unittest

class BiscuitTest(unittest.TestCase): def testEquals(self): theBiscuit = Biscuit('Ginger') myBiscuit = Biscuit('Ginger') assert_that(theBiscuit, equal_to(myBiscuit)) if __name__ == '__main__': unittest.main()

def test_hamcrest(self):
assert_that(0.1 * 0.1, close_to(0.01, 0.000000000000001))
#assert_that(0.1 * 0.1, close_to(0.01, 0.000000000000000001))
assert_that(
["a", "b", "c"],
all_of(
has_items("c", "d"),
has_items("c", "a")
)
)
 

插件六:结构体断言 jsonschema

官方文档: https://github.com/Julian/jsonschema 

实用场景: 我们在做断言时想把json的数据结构保存下来, 断言时不根据特定值来判断,而是根据整个返回的json数据结构来判断

 
 
schema=json.load(open("list_schema.json")) #"list_schema.json"是利用schema在线生成器生成的
validate(instance=r.json(), schema=schema) #validata对比传入的json数据与schema描述的数据结构是否一致
实例:
>> from jsonschema import validate >>> # A sample schema, like what we'd get from json.load() >>> schema = { ... "type" : "object", ... "properties" : { ... "price" : {"type" : "number"}, ... "name" : {"type" : "string"}, ... }, ... } >>> # If no exception is raised by validate(), the instance is valid. >>> validate(instance={"name" : "Eggs", "price" : 34.99}, schema=schema) >>> validate( ... instance={"name" : "Eggs", "price" : "Invalid"}, schema=schema, ... ) # doctest: +IGNORE_EXCEPTION_DETAIL Traceback (most recent call last): ... ValidationError: 'Invalid' is not of type 'number'

It can also be used from console:

$ jsonschema -i sample.json sample.schema
 

 插件七:模版断言 pystache

官方文档: https://github.com/defunkt/pystache

实用场景:做接口测试的数据准备时,接口的请求参数往往非常庞大,但是我们通常只想把特定的参数动态更新,其余的参数不改动

实例:

>>> import pystache
>>> print pystache.render('Hi {{person}}!', {'person': 'Mom'})
Hi Mom!
@classmethod
def parse(self, template_path, dict):
template = "".join(open(template_path).readlines())
#支持把temp中的{{值}} 替换成dict中给的值 temp中存放请求的json
return pystache.render(template, dict)

requests部分:

原文: https://foofish.net/http-requests.html

requests 的安装可以直接使用 pip 方法:pip install requests

>>> import requests
# GET 请求
>>> response = requests.get("https://foofish.net")

返回的时 Response 对象,Response 对象是 对 HTTP 协议中服务端返回给浏览器的响应数据的封装,响应的中的主要元素包括:状态码、原因短语、响应首部、响应体等等,这些属性都封装在Response 对象中。

# 状态码
>>> response.status_code
200

# 原因短语
>>> response.reason
'OK'

# 响应首部
>>> for name,value in response.headers.items():
...     print("%s:%s" % (name, value))
...
Content-Encoding:gzip
Server:nginx/1.10.2
Date:Thu, 06 Apr 2017 16:28:01 GMT

# 响应内容
>>> response.content

'<html><body>此处省略一万字...</body></html>

requests 除了支持 GET 请求外,还支持 HTTP 规范中的其它所有方法,包括 POST、PUT、DELTET、HEADT、OPTIONS方法。

>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> r = requests.delete('http://httpbin.org/delete')
>>> r = requests.head('http://httpbin.org/get')
>>> r = requests.options('http://httpbin.org/get')

构建请求查询参数

很多URL都带有很长一串参数,我们称这些参数为URL的查询参数,用"?"附加在URL链接后面,多个参数之间用"&"隔开,比如:http://fav.foofish.net/?p=4&s=20 ,现在你可以用字典来构建查询参数:

>>> args = {"p": 4, "s": 20}
>>> response = requests.get("http://fav.foofish.net", params = args)
>>> response.url
'http://fav.foofish.net/?p=4&s=2'

构建请求首部 Headers

requests 可以很简单地指定请求首部字段 Headers,比如有时要指定 User-Agent 伪装成浏览器发送请求,以此来蒙骗服务器。直接传递一个字典对象给参数 headers 即可。

>>> r = requests.get(url, headers={'user-agent': 'Mozilla/5.0'})

构建 POST 请求数据

requests 可以非常灵活地构建 POST 请求需要的数据,如果服务器要求发送的数据是表单数据,则可以指定关键字参数 data,如果要求传递 json 格式字符串参数,则可以使用json关键字参数,参数的值都可以字典的形式传过去。

作为表单数据传输给服务器

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)

作为 json 格式的字符串格式传输给服务器

>>> import json
>>> url = 'http://httpbin.org/post'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

Response中的响应体

HTTP返回的响应消息中很重要的一部分内容是响应体,响应体在 requests 中处理非常灵活,与响应体相关的属性有:content、text、json()。

content 是 byte 类型,适合直接将内容保存到文件系统或者传输到网络中

>>> r = requests.get("https://pic1.zhimg.com/v2-2e92ebadb4a967829dcd7d05908ccab0_b.jpg")
>>> type(r.content)
<class 'bytes'>
# 另存为 test.jpg
>>> with open("test.jpg", "wb") as f:
...     f.write(r.content)

text 是 str 类型,比如一个普通的 HTML 页面,需要对文本进一步分析时,使用 text。

>>> r = requests.get("https://foofish.net/understand-http.html")
>>> type(r.text)
<class 'str'>
>>> re.compile('xxx').findall(r.text)

如果使用第三方开放平台或者API接口爬取数据时,返回的内容是json格式的数据时,那么可以直接使用json()方法返回一个经过json.loads()处理后的对象。

>>> r = requests.get('https://www.v2ex.com/api/topics/hot.json')
>>> r.json()
[{'id': 352833, 'title': '在长沙,父母同住...

代理设置

当爬虫频繁地对服务器进行抓取内容时,很容易被服务器屏蔽掉,因此要想继续顺利的进行爬取数据,使用代理是明智的选择。如果你想爬取墙外的数据,同样设置代理可以解决问题,requests 完美支持代理。

import requests

proxies = {
  'http': 'http://10.10.1.10:3128',
  'https': 'http://10.10.1.10:1080',
}

requests.get('http://example.org', proxies=proxies)

超时设置

requests 发送请求时,默认请求下线程一直阻塞,直到有响应返回才处理后面的逻辑。如果遇到服务器没有响应的情况时,问题就变得很严重了,它将导致整个应用程序一直处于阻塞状态而没法处理其他请求。

>>> import requests
>>> r = requests.get("http://www.google.coma")
...一直阻塞中

正确的方式的是给每个请求显示地指定一个超时时间。

>>> r = requests.get("http://www.google.coma", timeout=5)
5秒后报错
Traceback (most recent call last):
socket.timeout: timed out

Session

HTTP协议是一中无状态的协议,为了维持客户端与服务器之间的通信状态,使用 Cookie 技术使之保持双方的通信状态。

有些网页是需要登录才能进行爬虫操作的,而登录的原理就是浏览器首次通过用户名密码登录之后,服务器给客户端发送一个随机的Cookie,下次浏览器请求其它页面时,就把刚才的 cookie 随着请求一起发送给服务器,这样服务器就知道该用户已经是登录用户。

import requests
# 构建会话
session  = requests.Session()
# 登录url
session.post(login_url, data={username, password})
# 登录后才能访问的url
r = session.get(home_url)
session.close()

构建一个session会话之后,客户端第一次发起请求登录账户,服务器自动把cookie信息保存在session对象中,发起第二次请求时requests 自动把session中的cookie信息发送给服务器,使之保持通信状态。

---恢复内容结束---

 

猜你喜欢

转载自www.cnblogs.com/1026164853qqcom/p/11298192.html