使用python和asyncio打造接口并發(fā)測試GUI工具
前言
接口并發(fā)測試是測試工程師日常工作中的重要一環(huán),而一個直觀的 GUI 工具能有效提升工作效率和體驗。本篇文章將帶你用 PyQt5 和 asyncio 從零實現(xiàn)一個美觀且功能實用的接口并發(fā)測試工具。
我們將實現(xiàn)以下功能:
請求方法選擇器
添加了一個下拉框 QComboBox,用戶可以選擇 GET、POST、PUT、DELETE 或 PATCH。
動態(tài)請求方法
根據(jù)用戶選擇的請求方法,在 send_request 函數(shù)中動態(tài)調(diào)用對應(yīng)的 aiohttp 方法(如 session.get 或 session.post)。
異常處理
如果用戶選擇了不支持的請求方法,會返回 "Unsupported Method" 錯誤。
使用方法
在界面上輸入請求的 URL。
選擇所需的 請求方法(如 GET、POST 等)。
輸入 請求頭 和 請求參數(shù)(JSON 格式)。
設(shè)置 并發(fā)請求次數(shù),點擊“開始測試”。
查看結(jié)果表格中每個請求的序號、狀態(tài)碼和響應(yīng)時間。
下面是完整的代碼實現(xiàn)以及詳細(xì)的注釋,幫助你快速上手。
代碼實現(xiàn)
1. 安裝依賴
在開始之前,請確保安裝了必要的依賴庫:
pip install pyqt5 aiohttp
2. 主代碼
以下是完整的代碼實現(xiàn):
import sys import asyncio import aiohttp from PyQt5.QtWidgets import ( QApplication, QWidget, QLabel, QLineEdit, QTextEdit, QVBoxLayout, QHBoxLayout, QPushButton, QSpinBox, QTableWidget, QTableWidgetItem ) from PyQt5.QtCore import Qt from PyQt5.QtGui import QFont class AsyncHttpTester(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): """初始化用戶界面""" self.setWindowTitle("接口并發(fā)測試工具") self.setGeometry(100, 100, 800, 600) self.setFont(QFont("Arial", 10)) # === 接口配置區(qū) === url_label = QLabel("請求 URL:") self.url_input = QLineEdit() self.url_input.setPlaceholderText("請輸入接口 URL") headers_label = QLabel("請求頭 (JSON 格式):") self.headers_input = QTextEdit() self.headers_input.setPlaceholderText('例如:{"Content-Type": "application/json"}') params_label = QLabel("請求參數(shù) (JSON 格式):") self.params_input = QTextEdit() self.params_input.setPlaceholderText('例如:{"key": "value"}') times_label = QLabel("發(fā)送次數(shù):") self.times_input = QSpinBox() self.times_input.setRange(1, 1000) self.times_input.setValue(1) # === 開始按鈕 === self.start_button = QPushButton("開始測試") self.start_button.clicked.connect(self.start_test) # === 結(jié)果展示區(qū) === results_label = QLabel("測試結(jié)果:") self.results_table = QTableWidget() self.results_table.setColumnCount(3) self.results_table.setHorizontalHeaderLabels(["請求序號", "狀態(tài)碼", "響應(yīng)時間 (秒)"]) self.results_table.setColumnWidth(0, 100) self.results_table.setColumnWidth(1, 100) self.results_table.setColumnWidth(2, 150) # === 布局 === layout = QVBoxLayout() # 接口配置布局 config_layout = QVBoxLayout() config_layout.addWidget(url_label) config_layout.addWidget(self.url_input) config_layout.addWidget(headers_label) config_layout.addWidget(self.headers_input) config_layout.addWidget(params_label) config_layout.addWidget(self.params_input) config_layout.addWidget(times_label) config_layout.addWidget(self.times_input) # 添加開始按鈕 config_layout.addWidget(self.start_button) # 結(jié)果展示布局 results_layout = QVBoxLayout() results_layout.addWidget(results_label) results_layout.addWidget(self.results_table) # 整合布局 layout.addLayout(config_layout) layout.addLayout(results_layout) self.setLayout(layout) async def send_request(self, session, url, headers, params, index): """發(fā)送單個 HTTP 請求""" try: async with session.post(url, json=params, headers=headers) as response: elapsed = response.elapsed.total_seconds() if response.elapsed else 0 return index, response.status, elapsed except Exception as e: return index, f"Error: {str(e)}", 0 async def start_async_requests(self, url, headers, params, times): """啟動并發(fā)請求""" tasks = [] async with aiohttp.ClientSession() as session: for i in range(times): tasks.append(self.send_request(session, url, headers, params, i + 1)) return await asyncio.gather(*tasks) def start_test(self): """開始測試按鈕事件""" url = self.url_input.text().strip() try: headers = eval(self.headers_input.toPlainText().strip()) if self.headers_input.toPlainText().strip() else {} params = eval(self.params_input.toPlainText().strip()) if self.params_input.toPlainText().strip() else {} except Exception as e: self.results_table.setRowCount(0) self.results_table.setRowCount(1) self.results_table.setItem(0, 0, QTableWidgetItem("Error")) self.results_table.setItem(0, 1, QTableWidgetItem(f"Invalid headers/params: {str(e)}")) return times = self.times_input.value() if not url: self.results_table.setRowCount(0) self.results_table.setRowCount(1) self.results_table.setItem(0, 0, QTableWidgetItem("Error")) self.results_table.setItem(0, 1, QTableWidgetItem("URL 不能為空")) return # 清空結(jié)果表 self.results_table.setRowCount(0) # 啟動異步任務(wù) loop = asyncio.get_event_loop() results = loop.run_until_complete(self.start_async_requests(url, headers, params, times)) # 更新結(jié)果表 self.results_table.setRowCount(len(results)) for i, (index, status, elapsed) in enumerate(results): self.results_table.setItem(i, 0, QTableWidgetItem(str(index))) self.results_table.setItem(i, 1, QTableWidgetItem(str(status))) self.results_table.setItem(i, 2, QTableWidgetItem(f"{elapsed:.2f}")) if __name__ == "__main__": app = QApplication(sys.argv) tester = AsyncHttpTester() tester.show() sys.exit(app.exec_())
功能解析
1. 界面設(shè)計
使用 PyQt5 構(gòu)建界面,布局由 QVBoxLayout 和 QHBoxLayout 組合,模塊化分為“配置區(qū)”和“結(jié)果區(qū)”。
支持輸入 URL、請求頭、請求參數(shù)、以及指定發(fā)送次數(shù)。
2. 異步請求
使用 aiohttp.ClientSession 實現(xiàn)非阻塞的 HTTP 請求。
通過 asyncio.gather 并發(fā)發(fā)送多個請求,收集結(jié)果。
3. 響應(yīng)展示
結(jié)果以表格形式展示,包含請求序號、狀態(tài)碼、響應(yīng)時間,方便對比和分析。
運(yùn)行效果
啟動工具后,用戶可以在界面上輸入接口參數(shù),例如 URL、請求頭、請求體等。
點擊“開始測試”后,工具會并發(fā)發(fā)送指定次數(shù)的請求,并實時展示結(jié)果。
總結(jié)
通過 PyQt5 和 asyncio,我們成功實現(xiàn)了一個美觀實用的接口并發(fā)測試工具。在這個項目中,測試工程師可以直觀地配置接口參數(shù)并分析響應(yīng)結(jié)果,同時也能深入理解 Python 的異步編程原理。
到此這篇關(guān)于使用python和asyncio打造接口并發(fā)測試GUI工具的文章就介紹到這了,更多相關(guān)python asyncio接口并發(fā)測試內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決TensorFlow調(diào)用Keras庫函數(shù)存在的問題
這篇文章主要介紹了解決TensorFlow調(diào)用Keras庫函數(shù)存在的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07Python 中 Virtualenv 和 pip 的簡單用法詳解
本篇文章主要介紹了Python 中 Virtualenv 和 pip 的簡單用法詳解,具有一定的參考價值,有興趣的可以了解一下2017-08-08Python字符串對齊方法使用(ljust()、rjust()和center())
這篇文章主要介紹了Python字符串對齊方法使用(ljust()、rjust()和center()),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04使用Python開發(fā)游戲運(yùn)行腳本實現(xiàn)模擬點擊
這篇文章主要介紹了使用Python開發(fā)游戲運(yùn)行腳本實現(xiàn)模擬點擊,這樣我們要想實現(xiàn)手游腳本開發(fā)的第一步,就是下載Android模擬器,然后在對安卓模擬器進(jìn)行鼠標(biāo)和鍵盤的模擬,以此來實現(xiàn)自動化游戲腳本,需要的朋友可以參考下2021-11-11Python將字符串常量轉(zhuǎn)化為變量方法總結(jié)
在本篇內(nèi)容里我們給大家整理了一篇關(guān)于Python將字符串常量轉(zhuǎn)化為變量方法的知識點總結(jié),有需要的朋友們學(xué)習(xí)下。2019-03-03