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
class TelnetClient(object):
"""通過telnet連線dubbo服務, 執行shell命令, 可用來呼叫dubbo介面
"""
def __init__(self, server_host, server_post):
self.tn = telnetlib.Telnet()
self.server_host = server_host
self.server_port = server_post
# 此函式實現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_post):
try:
self.telnet_client = TelnetClient(server_host, server_post)
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_post": 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_post=dubbo_info.get("server_post"))
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
實體類的欄位: ,填寫格式如下: "Id":123,"code":"abc"
{"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
- Httpclient 介面自動化HTTPclient
- python 介面自動化Python
- 全自動化介面
- 介面自動化與ui自動化區別UI
- 介面自動化從個人走向團隊協作開發
- 介面自動化測試錄製工具,讓python selenium自動化測試指令碼開發更加方便Python指令碼
- SOLIDWORKS二次開發外掛SolidKits助力企業實現BOM自動化Solid
- 介面自動化測試
- 使用 httprunner 做為自動化測試平臺執行引擎還是爽,感謝 httprunner 作者HTTP
- Python 介面自動化測試Python
- python介面自動化測試之python基礎語法Python
- 介面自動化之實現日誌記錄封裝封裝
- JMeter 介面自動化測試(手工轉自動化指令碼)JMeter指令碼
- 開源介面自動化測試專案--時默
- 介面自動化測試-apiAutoTest 優化之資料依賴處理API優化
- 介面自動化測試實戰之智慧場景如何攻破
- 介面自動化測試 - RobotFramework RESTinstanceFrameworkREST
- 三.介面自動化專案1
- 二、介面自動化測試(2)
- 介面自動化測試框架 HttpFPT框架HTTP
- 介面自動化大牛養成記
- 【pytest 介面自動化】token 問題
- protobuf 介面自動化測試摸索
- 介面自動化(四):框架搭建(Python)框架Python
- dubbo泛化引發的生產故障之dubbo隱藏的坑
- Python自動化開發學習6Python