接口測試庫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信息發送給服務器,使之保持通信狀態。

---恢復內容結束---

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM