若有任何學習問題,能夠添加做者微信:lockingfreehtml
課程目錄
Python接口測試實戰1(上)- 接口測試理論 Python接口測試實戰1(下)- 接口測試工具的使用 Python接口測試實戰2 - 使用Python發送請求 Python接口測試實戰3(上)- Python操做數據庫 Python接口測試實戰3(下)- unittest測試框架 Python接口測試實戰4(上) - 接口測試框架實戰 Python接口測試實戰4(下) - 框架完善:用例基類,用例標籤,從新運行上次失敗用例 Python接口測試實戰5(上) - Git及Jenkins持續集成 Python接口測試實戰5(下) - RESTful、Web Service及Mock Server前端
更多學習資料請加QQ羣: 822601020獲取java
本節內容
- REST及RESTful API
- Web Service
- XML解析
- Mock Server
REST及RESTful API
參考連接: https://blog.csdn.net/lch2848508/article/details/72729658node
REST:表述性狀態轉移或表現層狀態轉移,「表現」及每一個接口地址(URI)都表現爲(視爲)一個資源對象(文本資源、圖片資源、服務資源),狀態轉移指經過POST/PUT方法發送完整的新狀態信息來更改資源對象的狀態 如某https://api.***.com/user資源狀態爲{"name": "Kaka", "age": 30}
,咱們經過POST/PUT請求發送新狀態{"name": "Kaka", "age": 18}
來更新對象信息,完成狀態轉移git
URI 與URL的區別:URL值包含協議的連接,如
https://www.baidu.com
, 還有一種相對連接叫URN,如/doc/1.html
,這兩種都能惟必定位一個資源,URI(統一資源定位符)包含URL和URNgithub
RESTful API是一種接口設計風格或規範,主要有如下特色:數據庫
- 統一使用https協議
- 接口使用專用的api域名
https://api.example.com/
- 接口分版本管理
https://api.example.com/v1/
- 路徑又稱"終點"(endpoint),表示API的具體網址,路徑中只能包含名詞(表明資源對象),可使用複數來表明多個一個資源集合
https://api.example.com/v1/zoos
- 同一個接口提供多種請求方法,GET獲取資源信息,POST新建或更新資源,PUT/PATCH更新資源,DELETE刪除資源
- 能夠經過url參數過濾信息
https://api.example.com/v1/zoos?limit=10 # 獲取前10個
- 儘可能使用JSON, 避免使用XML
- 身份認證推薦使用OAuth2.0,或Basic Auth,token等,避免使用Cookie和Session(RESTful強調無狀態的設計)
示例:json
https://api.github.com 受權 Basic Auth (superhin001, ***) 或 Oauth 2.0 Access Token: 1c4f679300f29ee4e7041028d49e504b9da145b1
flask
GET https://api.github.com/user 獲取用戶信息 後端
POST/PATCH https://api.github.com/user 修改用戶信息 POST/PATCH 數據
{ "login": "superhin001", "id": 21163682, "node_id": "MDQ6VXNlcjIxMTYzNjgy", "avatar_url": "https://avatars3.githubusercontent.com/u/21163682?v=4", "gravatar_id": "", "url": "https://api.github.com/users/superhin001", "html_url": "https://github.com/superhin001", "followers_url": "https://api.github.com/users/superhin001/followers", "following_url": "https://api.github.com/users/superhin001/following{/other_user}", "gists_url": "https://api.github.com/users/superhin001/gists{/gist_id}", "starred_url": "https://api.github.com/users/superhin001/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/superhin001/subscriptions", "organizations_url": "https://api.github.com/users/superhin001/orgs", "repos_url": "https://api.github.com/users/superhin001/repos", "events_url": "https://api.github.com/users/superhin001/events{/privacy}", "received_events_url": "https://api.github.com/users/superhin001/received_events", "type": "User", "site_admin": false, "name": "我是韓老師", "company": null, "blog": "", "location": null, "email": "superhin@126.com", "hireable": null, "bio": null, "public_repos": 3, "public_gists": 0, "followers": 0, "following": 0, "created_at": "2016-08-22T01:12:32Z", "updated_at": "2018-09-14T02:33:43Z", "private_gists": 0, "total_private_repos": 0, "owned_private_repos": 0, "disk_usage": 45430, "collaborators": 0, "two_factor_authentication": false, "plan": { "name": "free", "space": 976562499, "collaborators": 0, "private_repos": 0 } }
GET https://api.github.com/user/keys 獲取用戶全部SSH-Key信息
POST https://api.github.com/user/keys 新建Key
POST 數據
{ "id": 30742411, "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfsTJs7mNWstJ+tO6O1jQHKdDdnldqlqkO0gAune9EH7oqICD1hP7c1duNZwvNnvyGa7SyqamIpNXmSYv303FEVAXzPsb9MzCChG16gzevQtbIX4Qt7vFOsHNSCikSCD/s6DMa0Koryiu7Yju5mW9UUnjVM+a1P80SOiK7p2UBQPFVKRrUtr0htV3U6a2rdP51Vzm2UCjChTUa4q7L3m4C7oB9aSvUsNTk+PmuJlAer4oOd7FsNPqD1Or3lRKAmgxbTX4xTaOkwibK0t2eYkh/VTUPMQ9wDwpa4hZLiEq9qSew3McCwsl70k4H0H4F/VwV2sSCXqZu274YmNDT5Hl3 hanzhichao@hanzhichao01", "title": "test3", "verified": true, "created_at": "2018-09-14T09:54:51Z", "read_only": false }
Web Service
Web Service 是一種跨平臺(Java對象,Python也能夠調用)RPC(遠程方法調用)解決方案。 基於SOAP協議,使用XML這種跨平臺語言傳輸對遠程方法的調用信息及返回結果,並提供WSDL接口描述服務
- SOAP:簡單面向對象協議, 基於XML語言,使用HTTP協議傳輸
- XML: 可擴展標記語言,同JSON同樣是一種跨平臺語言
- WSDL: Web Service服務描述語言,提供遠程對象的調用描述信息(相似於接口文檔,XML格式)
SOAP格式
SOAP協議基於XML語言, SOAP消息體首先必須有個信封(Enelope),信封中能夠有信息頭(Header)和信息體(Body),其中Body中還能夠包含錯誤信息(Fault) 基本格式以下:
<!-- 信封固定格式 指定命名空間爲soapenv --> <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2001/12/soap-envelope" soapenv:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soapenv:Header> <!--信息頭 可選,可寫成但標籤--> ...... </soapenv:Header> <soapenv:Body> <!--信息體 實際調用內容--> ...... </soapenv:Body> </soap:Envelope>
使用SoupUI 示例接口: http://115.28.108.130:4000/?wsdl
因爲Postman等不具有將wsdl接口信息解析成對象描述的功能,咱們使用另外一個SOAP接口專用的測試工具SoupUI
SoupUI下載地址: http://www.wmzhe.com/soft-32815.html
1.新建項目
2.發送接口
使用Fiddler抓包,查看raw格式:
POST http://115.28.108.130:4000/ HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: text/xml;charset=UTF-8 SOAPAction: "addUser" Content-Length: 370 Host: 115.28.108.130:4000 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5) <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="UserService"> <soapenv:Header/> <soapenv:Body> <user:addUser> <!--Optional:--> <user:name>范冰冰</user:name> <!--Optional:--> <user:password>123456</user:password> </user:addUser> </soapenv:Body> </soapenv:Envelope>
使用Postman發送SOAP接口
text/xml 和 application/xml的區別: 當你<?xml version='1.0' encoding='UTF-8'>指定編碼的時候,使用application/xml會安裝xml指定的編碼傳輸,而使用text/html會默認使用us-ascii編碼編碼傳輸數據
使用Python操做Web service接口
pip install suds-jurko
from suds.client import Client service = Client("http://115.28.108.130:4000/?wsdl").service # 獲取遠端服務對象 result = service.addUser("范冰冰", "123456") # 向本地方法同樣調用 print(result) # 輸出 用戶已存在
使用requests庫發送
import requests url = 'http://115.28.108.130:4000/' data = '''<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:user="UserService"> <soapenv:Header/> <soapenv:Body> <user:addUser> <!--Optional:--> <user:name>張三</user:name> <!--Optional:--> <user:password>123456</user:password> </user:addUser> </soapenv:Body> </soapenv:Envelope> '''.encode('utf-8') res = requests.post(url=url,data=data) print(res.text)
結果:
<?xml version='1.0' encoding='UTF-8'?> <soap11env:Envelope xmlns:soap11env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="UserService"><soap11env:Body><tns:addUserResponse><tns:addUserResult>用戶已存在</tns:addUserResult></tns:addUserResponse></soap11env:Body></soap11env:Envelope>
XML解析
XML: 可擴展標記語言,使用<tag></tag>標籤,多級樹狀結構,多用來存儲和傳輸數據,如:
<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore>
- 根元素(根節點),父元素,子元素,同級元素:bookstore爲根元素,book是title的父元素,title是book的子元素,title和author是同級元素
- 標籤,屬性,文本:bookstore boot title等爲標籤(元素節點),boot中category="COOKING" category爲屬性,COOKING爲屬性值,<title></title>之間的Everyday Italian爲文本
Python解析XML
- 加載元素樹(ElementTree)獲得根節點
- 從根節點使用xpath查找其餘節點
from xml.etree import ElementTree d = '''<bookstore> <book category="COOKING"> <title lang="en">Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book> <book category="CHILDREN"> <title lang="en">Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book> <book category="WEB"> <title lang="en">Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book> </bookstore> ''' root = ElementTree.fromstring(d) # 加載元素樹(ElementTree)獲得根節點 print(root.find(".")) # 選擇當前節點 print(root.find("book")) # 選擇標籤爲book的子節點 print(root.find("book[2]")) # 選擇標籤爲book的第三個子節點 print(root.find("book[@category='COOKING']")) # 選擇標籤爲book切標籤屬性爲category="COOKING" print(root.find("./book/[title='Harry Potter']")) # 選擇標籤爲book的節點中包含子標籤title 切title的文本內容爲Harry Potter
結果:
<Element 'bookstore' at 0x000002406B666688> <Element 'book' at 0x000002406B6666D8> <Element 'book' at 0x000002406B8600E8> <Element 'book' at 0x000002406B6666D8> <Element 'book' at 0x000002406B8600E8>
find()返回的是節點對象,能夠經過.tag獲取標籤名,.attrib獲取屬性字典,.text獲取文本
XPath選擇器
- 路徑: 按路徑選擇
- 標籤名: 選定全部該名的標籤
- *: 選定全部元素
- . : 選擇當前節點
- ..: 選擇上級節點
- //: 選擇當前元素下全部級別的元素
- [@屬性名]:選擇全部具備當前屬性的元素
- [@屬性名=屬性值]: 選擇屬性=屬性值的元素
- [子標籤名]:選擇具備當前子標籤的元素
- [子標籤名='文本']: 選擇子標籤文本的元素
經常使用的三種定位元素方法
- 從根節點按路徑選擇: root.find("./book[3]/title")
- 按屬性並結合相對路徑選擇: root.find(book[@category='WEB']/title)
- 按所包含的獨特子標籤選擇: root.find(book[title='Harry Potter']/title)
Mock Server
Mock 即模擬,就是在測試過程當中,對於某些不容易構造或者不容易獲取的對象,用一個虛擬的對象來建立以便測試的測試方法,其最大的優點就是降級先後端耦合度,使前端工程師能夠不依賴後端返回數據,先開發前端樣式以及邏輯處理 簡單來講: Mock是用瞭解決依賴問題的,將複雜的/不穩定的/還未創建的依賴對象用一個簡單的假對象來代替
Mock Server 即Mock接口服務器,能夠經過配置快速Mock出新的接口 Mock Server的使用範圍
- 先後端分離項目
- 所測接口依賴第三方系統(還未具有)
- 所測接口依賴複雜或依賴的接口不穩定,並不做爲主要驗證對象
同時在接口還未開發好時,提供Mock接口(假接口)會比只有接口文檔更直觀,並能有效減小溝通成本和一些文檔理解bug
Postman的Mock Server功能
Postman還能夠基於Collection創建Mock Server,這裏再也不詳述
Python+Flask本身搭建Mock接口 使用Flask包咱們能夠快速搭建Mock接口
pip install flask
from flask import Flask, request, jsonify, abort import random app = Flask(__name__) # 實例化一個Flask對象 @app.route("/api/user/reg/", methods=["POST"]) def reg(): if not request.json or not 'name' in request.json or not 'password' in request.json: abort(404) res = [ { "code": "100000", "msg": "成功", "data": { "name": "李六", "password": "e10adc3949ba59abbe56e057f20f883e" } }, { "code": "100001", "msg": "失敗,用戶已存在", "data": { "name": "李六", "password": "e10adc3949ba59abbe56e057f20f883e" } }, { "code": "100002", "msg": "失敗,添加用戶失敗", "data": { "name": "李六", "password": "e10adc3949ba59abbe56e057f20f883e" } } ] return jsonify(random.choice(res)) if __name__ == '__main__': app.run()
此爲北京龍騰育才 Python高級自動化(接口測試部分)授課筆記 課程介紹 想要參加現場(北京)/網絡課程的能夠聯繫做者微信:lockingfree
- 高效學習,快速掌握Python自動化全部領域技能
- 同步快速解決各類問題
- 配套實戰項目練習
原文出處:https://www.cnblogs.com/superhin/p/10339004.html