HttpRunner 二次開發之 Dubbo 介面自動化
國內大部分公司目前都是使用基於 Java 語言的 Dubbo 技術棧,而測試同事普遍對 Python 技術棧更為熟悉。為了使不懂 JAVA 程式碼的測試同事也能進行 Dubbo 介面層的測試,故對 HttpRunner 進行二次開發,新增對 Dubbo 介面的支援
1、實現原理
關於 HttpRunner 我想不用多做介紹,測試小夥伴應該都瞭解,這是一款非常優秀的面向 HTTP(S) 協議的通用測試框架,我們要做的是基於這個框架進行二次開發。
根據 Dubbo 官方文件中提到的:dubbo 可以透過 telnet 命令進行服務治理,詳情見Dubbo 官方文件
而在 Python 中有一個第三方包 telnetlib,所以我們可以透過這個包來執行 telnet 命令,進而對 dubbo 介面進行呼叫
透過上圖我們還了解到一個資訊點,那就是如果我要透過 telnet 連線伺服器,我需要 ip 還有 埠號。下面,讓我們一步步來實現
2、Dubbo 服務圖解
我們可以透過 Dubbo 服務的架構圖瞭解到,要獲取 Dubbo 服務,我們需要去 zookeeper 服務註冊中心找到對應的服務即可
3、telnet 連線 Dubbo 服務
使用 Docker 容器部署微服務,每次重啟服務 ip 都會發生變化(原因:容器間則不用 ip 直接通訊,而使用主機名、復服務名、網路別名),所以在使用 telnet 連線時需要獲取動態的 ip,我司專案目前使用的 dubbo-monitor 進行管理
透過爬蟲的思想,可動態獲取服務 ip 和埠號,連線上伺服器之後,我們就可以透過模擬命令列對服務進行治理
4、如何使用
4.1、請求服務相關程式碼
這段程式碼是處理請求的程式碼,放在 httprunner 原始碼檔案下的 utils 資料夾內
import time
import os
import sys
import telnetlib
class TelnetClient(object):
"""透過telnet連線dubbo服務, 執行shell命令, 可用來呼叫dubbo介面
"""
def __init__(self, server_host, server_port):
self.tn = telnetlib.Telnet()
self.server_host = server_host
self.server_port = server_port
# 此函式實現telnet登入主機
def connect_dubbo(self):
try:
print("telent連線dubbo服務端: telnet {} {} ……".format(self.server_host, self.server_port))
self.tn.open(self.server_host, port=self.server_port)
return True
except Exception as e:
print('連線失敗, 原因是: {}'.format(str(e)))
return False
# 執行傳過來的命令,並輸出其執行結果
def execute_some_command(self, command):
# 執行命令
cmd = (command + '\n').encode("gbk")
self.tn.write(cmd)
# 獲取命令結果,字串型別
retry_count = 0
# 如果響應未及時返回,則等待後重新讀取,並記錄重試次數
result = self.tn.read_very_eager().decode(encoding='gbk')
while result == '':
time.sleep(1)
result = self.tn.read_very_eager().decode(encoding='gbk')
retry_count += 1
return result
# 退出telnet
def logout_host(self):
self.tn.write(b"exit\n")
print("登出成功")
class InvokeDubboApi(object):
def __init__(self, server_host, server_port):
try:
self.telnet_client = TelnetClient(server_host, server_port)
self.login_flag = self.telnet_client.connect_dubbo()
except Exception as e:
print("invokedubboapi init error" + str(e))
def invoke_dubbo_api(self, dubbo_service, dubbor_method, *args):
api_name = dubbo_service + "." + dubbor_method + "{}"
cmd = "invoke " + api_name.format(args)
print("呼叫命令是:{}".format(cmd))
resp0 = None
try:
if self.login_flag:
resp0 = self.telnet_client.execute_some_command(cmd)
print("介面響應是,resp={}".format(resp0))
# dubbo介面返回的資料中有 elapsed: 4 ms. 耗時,需要使用elapsed 進行切割
return str(re.compile(".+").findall(resp0).pop(0)).split("elapsed").pop(0).strip()
else:
print("登陸失敗!")
except Exception as e:
raise Exception("呼叫介面異常, 介面響應是resp={}, 異常資訊為:{}".format(resp0, str(e)))
self.logout()
def logout(self):
self.telnet_client.logout_host()
class GetDubboService2(object):
def __init__(self):
pass
def get_dubbo_info2(self,content):
try:
dubbore = re.compile(r"([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)", re.I)
result = dubbore.search(str(content)).group()
print("獲取到dubbo部署資訊" + result)
return {"server_host": result.split(":")[0], "server_port": result.split(":")[1]}
except Exception as e:
raise Exception("獲取dubbo部署資訊失敗:{}".format(str(e)))
這段程式碼放在 functions 中,這樣在 yml 檔案中可以直接透過 ${方法名}進行呼叫
程式碼如下:
def invoke_dubbo2(content, dubbo_service, dubbo_method, *args):
'''
透過 zk管理後臺查詢dubbo註冊資訊
:param dubbo_service: dubbo中 服務名 如:com.zl.mall.api.IItemService
:param dubbor_method: 服務中的方法 如:updateItem
:param args: 方法請求需要的引數
:return:
'''
dubbo_info = GetDubboService2().get_dubbo_info2(content)
invokeDubboApi = InvokeDubboApi(server_host=dubbo_info.get("server_host"),
server_port=dubbo_info.get("server_port"))
return invokeDubboApi.invoke_dubbo_api(dubbo_service, dubbo_method, *args)
將程式碼新增至框架之後,即可在 yml 檔案中使用
4.2、新增 testcase
和在專案中填寫 Http testcase 類似,其中新增的幾個 variables 引數為
dubbo_service: com.zl.item.api.IItemService ---Dubbo 服務名稱(必填)
dubbo_method: queryItemByLstItemId ---Dubbo 服務方法名(必填)
iItemIdList: [123,12323] ---方法的請求引數(根據 Dubbo 定義的方法來調整入參)
${invoke_dubbo2()} 請求 dubbo 介面的方法,按照對應的格式填寫即可請求 DUbbo 介面
4.3、執行 testcase
執行 testcase,檢視控制檯資訊,其中 resp 即為 dubbo 介面返回的資訊,對比 validate 中設定的預期值,即可完成對 Dubbo 介面的測試
5、注意事項
5.0、請求引數異常
請求 Dubbo 介面如果填入的引數有誤,會報 no such method 的錯誤,請檢查一下引數是否正常
5.1、列舉類請求:
列舉類的類名: com.zl.item.entity.StudentEnum
需要使用到的列舉類:GOOD_STUDENT,填寫格式如下 :
{"name": "GOOD_STUDENT", "class": "com.zl.item.entity.StudentEnum "}
5.2、實體類請求:
實體類類名:com.zl.item.entity.Student
實體類的欄位:
public class student{
Long id;
String code}
{"class":"com.zl.item.entity.Student","Id":123,"code":"abc"}
5.3、對於請求方法是 void 方法的校驗設定
java 程式碼中 void 這種方法是沒有返回值的,所以我們直接用 “null”。如果需要進一步校驗資料的準確性,可以校驗這個方法改變的特性
5.4、對於入參是 Boolean 型別的資料
在 json 中,直接 使用{“data”:true}即可,但是在 python 請求時需要使用 “true”,加上雙引號
相關文章
- 介面自動化之介面整理(抓包)
- 測試開發之介面篇-使用K6完成介面自動化測試
- 基於 HttpRunner 的介面自動化測試平臺宣講 (已落地)HTTP
- 介面自動化實戰之框架搭建框架
- 測試開發之自動化篇-自動化測試框架設計框架
- 基於 HttpRunner + Django + Vue + Element UI 的介面自動化測試平臺,生產可用HTTPDjangoVueUI
- 測試開發之自動化篇-Appium指令碼開發APP指令碼
- JMeter介面自動化發包與示例JMeter
- python介面自動化測試之介面資料依賴Python
- 測試開發全棧之 Python 自動化全棧Python
- 介面自動化之引數動態生成替換
- Python之介面自動化初級:開始一個簡單的介面測試Python
- python 介面自動化Python
- 全自動化介面
- Httpclient 介面自動化HTTPclient
- 介面自動化從個人走向團隊協作開發
- 介面自動化與ui自動化區別UI
- 介面自動化測試錄製工具,讓python selenium自動化測試指令碼開發更加方便Python指令碼
- SOLIDWORKS二次開發外掛SolidKits助力企業實現BOM自動化Solid
- 介面自動化測試
- 使用 httprunner 做為自動化測試平臺執行引擎還是爽,感謝 httprunner 作者HTTP
- Python 介面自動化測試Python
- python介面自動化測試之python基礎語法Python
- 介面自動化之實現日誌記錄封裝封裝
- JMeter 介面自動化測試(手工轉自動化指令碼)JMeter指令碼
- 開源介面自動化測試專案--時默
- 介面自動化測試-apiAutoTest 優化之資料依賴處理API優化
- 介面自動化測試實戰之智慧場景如何攻破
- protobuf 介面自動化測試摸索
- 【pytest 介面自動化】token 問題
- 三.介面自動化專案1
- 介面自動化測試框架 HttpFPT框架HTTP
- 二、介面自動化測試(2)
- 介面自動化(四):框架搭建(Python)框架Python
- 介面自動化測試 - RobotFramework RESTinstanceFrameworkREST
- 介面自動化大牛養成記
- 淺談pytest+HttpRunner如何展開介面測試HTTP
- Python自動化開發學習6Python