用 PyQt5 和 asyncio 打造接口并發測試 GUI 工具

接口并發測試是測試工程師日常工作中的重要一環,而一個直觀的 GUI 工具能有效提升工作效率和體驗。本篇文章將帶你用 PyQt5 和 asyncio 從零實現一個美觀且功能實用的接口并發測試工具。

我們將實現以下功能:

  1. 請求方法選擇器
    添加了一個下拉框 QComboBox,用戶可以選擇 GETPOSTPUTDELETEPATCH

  2. 動態請求方法
    根據用戶選擇的請求方法,在 send_request 函數中動態調用對應的 aiohttp 方法(如 session.getsession.post)。

  3. 異常處理
    如果用戶選擇了不支持的請求方法,會返回 "Unsupported Method" 錯誤。


使用方法

  1. 在界面上輸入請求的 URL
  2. 選擇所需的 請求方法(如 GETPOST 等)。
  3. 輸入 請求頭請求參數(JSON 格式)。
  4. 設置 并發請求次數,點擊“開始測試”。
  5. 查看結果表格中每個請求的序號、狀態碼和響應時間。

下面是完整的代碼實現以及詳細的注釋,幫助你快速上手。
在這里插入圖片描述


代碼實現

1. 安裝依賴

在開始之前,請確保安裝了必要的依賴庫:

pip install pyqt5 aiohttp

2. 主代碼

以下是完整的代碼實現:

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 QFontclass AsyncHttpTester(QWidget):def __init__(self):super().__init__()self.init_ui()def init_ui(self):"""初始化用戶界面"""self.setWindowTitle("接口并發測試工具")self.setGeometry(100, 100, 800, 600)self.setFont(QFont("Arial", 10))# === 接口配置區 ===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("請求參數 (JSON 格式):")self.params_input = QTextEdit()self.params_input.setPlaceholderText('例如:{"key": "value"}')times_label = QLabel("發送次數:")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)# === 結果展示區 ===results_label = QLabel("測試結果:")self.results_table = QTableWidget()self.results_table.setColumnCount(3)self.results_table.setHorizontalHeaderLabels(["請求序號", "狀態碼", "響應時間 (秒)"])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)# 結果展示布局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):"""發送單個 HTTP 請求"""try:async with session.post(url, json=params, headers=headers) as response:elapsed = response.elapsed.total_seconds() if response.elapsed else 0return index, response.status, elapsedexcept Exception as e:return index, f"Error: {str(e)}", 0async def start_async_requests(self, url, headers, params, times):"""啟動并發請求"""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)}"))returntimes = 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# 清空結果表self.results_table.setRowCount(0)# 啟動異步任務loop = asyncio.get_event_loop()results = loop.run_until_complete(self.start_async_requests(url, headers, params, times))# 更新結果表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. 界面設計

  • 使用 PyQt5 構建界面,布局由 QVBoxLayoutQHBoxLayout 組合,模塊化分為“配置區”和“結果區”。
  • 支持輸入 URL、請求頭、請求參數、以及指定發送次數。

2. 異步請求

  • 使用 aiohttp.ClientSession 實現非阻塞的 HTTP 請求。
  • 通過 asyncio.gather 并發發送多個請求,收集結果。

3. 響應展示

  • 結果以表格形式展示,包含請求序號、狀態碼、響應時間,方便對比和分析。

運行效果

  1. 啟動工具后,用戶可以在界面上輸入接口參數,例如 URL、請求頭、請求體等。
  2. 點擊“開始測試”后,工具會并發發送指定次數的請求,并實時展示結果。

總結

通過 PyQt5 和 asyncio,我們成功實現了一個美觀實用的接口并發測試工具。在這個項目中,測試工程師可以直觀地配置接口參數并分析響應結果,同時也能深入理解 Python 的異步編程原理。

趕緊試試吧!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/902722.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902722.shtml
英文地址,請注明出處:http://en.pswp.cn/news/902722.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

理解npm的工作原理:優化你的項目依賴管理流程

目錄 什么是npm npm核心功能 npm 常用指令及其作用 執行npm i 發生了什么? 1. 解析命令與參數 2. 檢查依賴文件 3. 依賴版本解析與樹構建 4. 緩存檢查與包下載 5. 解壓包到 node_modules 6. 更新 package-lock.json 7. 處理特殊依賴類型 8. 執行生命周期腳本 9. …

React Native 安卓端 android Image 播放gif webp 動態圖

React Native 安卓端 android Image 播放gif webp 動態圖 RN項目是0.78.2 React是19.0 基本介紹 Image 是 React Native 中用于顯示各種類型圖片的核心組件,支持顯示網絡圖片、靜態資源、本地圖片以及 base64 編碼的圖片。在 Android 端,Image 組件還可…

實時數字人——DH_LIVE

前兩天親手搭建了實時對話數字人VideoChat,今天來搭建下DH_LIVE。 DH_LIVE一個實時數字人解決方案,從輸入文字到數字人對口型說話用時2-3秒。 今天就來實際操作下dh_live的搭建過程。 首先貼上git地址:https://github.com/kleinlee/DH_liv…

AOSP CachedAppOptimizer 凍結方案

背景 Android 一直面臨一個核心難題:如何優化進程對有限系統資源(如 CPU、電量)的使用,同時保證用戶體驗。 當進程進入后臺后,它們雖不再貢獻用戶體驗,卻仍可能消耗資源。傳統的殺后臺方案雖然節省資源&a…

實體店的小程序轉型之路:擁抱新零售的密碼-中小企實戰運營和營銷工作室博客

實體店的小程序轉型之路:擁抱新零售的密碼-中小企實戰運營和營銷工作室博客 在當今數字化浪潮的沖擊下,實體店面臨著前所未有的挑戰,但小程序的出現為實體店轉型新零售帶來了新的曙光。先來看一組驚人的數據,據相關統計&#xff…

Java求職面試:從Spring Boot到微服務的全面考核

Java求職面試實錄:從Spring Boot到微服務的全面考核 第一輪:基礎技術的考察 場景: 趙大寶走進了一家互聯網大廠的面試間,面試官嚴肅地看著他。 面試官: 趙大寶,你好。我們先從簡單的開始。請你解釋一下J…

記錄一個坑關于STM32 ARM Compiler Version

在用 Keil 進行 STM32 開發的時候,一開始下載,下載的 ARM 編譯器是 Version6,他就不兼容老的代碼,就很抽象。 所以必須要更換編譯器。 可以去官網下載編譯器 Downloads - Arm Developer ,也可以自己找資源哈&#xff…

PCIe體系結構學習入門——PCI總線概述(二)PCI總線的橋和配置

這里寫目錄標題 序言存儲器域和 PCI 總線域HOST 主橋PCI 橋和 PCI 設備配置空間PCI 橋PCI 設備配置空間PCI 總線的配置非透明 PCI 橋序言 接續前章內容,本章繼續講述 PCI 總線概述的第二部分——PCI 總線的橋和配置。 如果需要進一步了解前一章節內容,可以訪問:PCIe體系結構…

潯川代碼編輯器v2.0(測試版)更新公告

潯川代碼編輯器v2.0(測試版)更新公告 發布日期:** 2023年4月30日 我們很高興地宣布潯川代碼編輯器v2.0測試版即將上線!本次更新帶來了多項功能改進和問題修復,旨在為用戶提供更穩定、更強大的編程體驗。 主要更新內容 1. **Bug修復與穩定性提…

微信小程序 tabbar底部導航欄

官方文檔:https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html#tabBar 一、常規菜單格式 在app.json 文件中配置,其他關鍵點詳見官方文檔,后續更新不規則圖標的寫法

Spring 中@Autowired,@Resource,@Inject 注解實現原理

使用案例 前置條件: 現在有一個 Vehicle 接口,它有兩個實現類 Bus 和 Car ,現在還有一個類 VehicleService 需要注入一個 Vehicle 類型的 Bean: public interface Vehicle {}Component public class Car implements Vehicle {}C…

【Rust結構體】Rust結構體詳解:從基礎到高級應用

?? 歡迎大家來到景天科技苑?? 🎈🎈 養成好習慣,先贊后看哦~🎈🎈 🏆 作者簡介:景天科技苑 🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,…

《LightLLM:開啟大語言模型推理新時代》

《LightLLM:開啟大語言模型推理新時代》 大語言模型推理的困境與挑戰 在當今人工智能飛速發展的時代,大語言模型(LLMs)無疑是最為耀眼的明星技術之一。從 OpenAI 的 GPT 系列到谷歌的 BERT,再到國內如百度文心一言、阿里通義千問等,大語言模型以其強大的語言理解和生成能…

【Python Web開發】02-Socket網絡編程02

文章目錄 1. 服務器端1.1 socket.socket()1.2 socket.bind()1.3 socket.listen()1.4 socket.accept()1.5 socket.recv()1.6 socket.send() 和 socket.sendall()1.7 socket.close() 2. 客戶端2.1 socket.socket()2.2 socket.connect()2.3 socket.send() 和 socket.sendall()2.4 …

Flutter 在全新 Platform 和 UI 線程合并后,出現了什么大坑和變化?

Flutter 在全新 Platform 和 UI 線程合并后,出現了什么大坑和變化? 在兩個月前,我們就聊過 3.29 上《Platform 和 UI 線程合并》的具體原因和實現方式,而事實上 Platform 和 UI 線程合并,確實為后續原生語言和 Dart 的…

藍橋杯 1. 四平方和

四平方和 原題目鏈接 題目描述 四平方和定理(又稱拉格朗日定理)指出: 每個正整數都可以表示為 至多 4 個正整數的平方和。 如果將 0 包括進去,則每個正整數都可以恰好表示為 4 個非負整數的平方和。 例如: 5 0 …

開發并發布一個屬于自己的包(npm)

一、CommonJS規范導入require 創建一個npm包涉及幾個步驟,包括設置你的項目結構、編寫代碼、編寫文檔、測試你的代碼,以及發布到npm倉庫。以下是一個基本的指南,幫助你從頭開始創建一個npm包。 步驟 1: 初始化npm項目 創建項目文件夾&#x…

CRTP(Curiously Recurring Template Pattern)

C 中的 CRTP(奇異遞歸模板模式) CRTP(Curiously Recurring Template Pattern)是一種利用模板繼承實現 靜態多態(Static Polymorphism) 的設計模式。通過基類模板以派生類作為模板參數,CRTP 允許…

小白工具視頻轉MPG, 功能豐富齊全,無需下載軟件,在線使用,超實用

在視頻格式轉換需求日益多樣的今天,小白工具網的在線視頻轉 MPG 功能https://www.xiaobaitool.net/videos/convert-to-mpg/ )脫穎而出,憑借其出色特性,成為眾多用戶處理視頻格式轉換的優質選擇。 從格式兼容性來看,它支…

銀河麒麟系統離線安裝nodejs

本篇文章我們介紹如何通過nvm(node版本管理工具)來實現離線安裝nodejs 第一步:下載nvm https://github.com/nvm-sh/nvm/releases/tag/v0.40.1 在頁面找到【Source code(tar.gz)】下載 第二步:安裝nvm 將下載好的tar.gz拷貝到銀河麒麟系統文件夾下(加…