接口测试工具实战-调试发布

本文介绍了如何使用Python结合requests库和Qt GUI框架开发了一个集成接口测试工具,具备GUI界面、多线程处理以及exe打包功能。同时,还展示了如何利用gevent实现端口扫描工具的高效并发扫描。
摘要由CSDN通过智能技术生成

一、需求分析
1.开发需求
版本:V1…0
需求:实现一个接口测试工具,带GUI页面样式
功能描述:
1)测试实现接口测试
2)方便测试人员操作
在这里插入图片描述

二、实现方案
1)GUI编程
2)接口requests库

三、代码封装调试
1.GUI界面设计
2.接口代码封装
3.综合调试
requests库使用:
在这里插入图片描述

四、接口工具优化
1.多线程操作提高效率
2.自动调整布局
3.导出exe可执行文件

五、打包
ui文件和py文件放到一个文件夹,cmd切换到文件夹,输入命令
1.Windows平台打包exe可执行文件
在这里插入图片描述
2.Mac平台打包exe可执行文件
在这里插入图片描述
命令-F解释:
产生一个文件用于部署

遇到运行不了的问题:
在这里插入图片描述
解决:把ui文件放到py文件同级目录

六、接口测试工具代码实现
接口测试工具.py

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'untitled.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
# 1- 需要运行qt的gui程序,必须创建一个app对象
import json
import requests
import threading
from PySide2.QtWidgets import QApplication
# 2- 需要打开一个UI文件
from PySide2.QtCore import QFile
# 3- py代码需要加载ui文件
from PySide2.QtUiTools import QUiLoader  # 需要 加载设计的ui文件

"""
处理逻辑:
    1- 发送请求
        1- 获取对应请求方法
            4个方法:GET POST PUT DELETE
            解决方案:
                1- if elif elif else-------request.get/post/put/delete
                2- request.Request(method, url) 接收一个请求对象
        2- 获取url
        3- 获取body
        4- 获取请求头
        5- 点击发送
    2- 接收响应数据

"""


class HttpClient:
    def __init__(self):
        qFile = QFile('接口测试工具.ui')  # 文件对象
        qFile.open(QFile.ReadOnly)  # 只读方式
        # 6- 加载对象--生成一个ui对象
        self.ui = QUiLoader().load(qFile)
        qFile.close()  # 关闭qfile
        self.ui.pushButton.clicked.connect(self.request_send)  # 发送请求

    def request_send(self):
        # 1- 获取方法
        method = self.ui.method_comboBox.currentText()
        # 2- 获取url
        url = self.ui.lineEdit.text()
        # 3- 获取请求头---字符串
        header = self.ui.HeaderplainText.toPlainText()
        if header.strip() != '':
            header = json.loads(header)
        # 4- 获取请求体---字符串
        payload = self.ui.bodyplainTextEdit.toPlainText()
        if payload.strip() != '':
            payload = json.loads(payload)
        # 5- 发送请求
        req = requests.Request(method, 'http://' + url, headers=header, data=payload)
        prepare = req.prepare()  # 获取请求前数据信息
        self.print_request(prepare)
        s = requests.session()  # 创建个会话对象
        # 发送请求是阻塞模式!
        thread1 = threading.Thread(target=self.thread_func, args=(s, prepare))
        thread1.start()

    # 多线程发送函数
    def thread_func(self, s, prepare):
        # 发请求
        resp = s.send(prepare)  # 返回值是 响应体
        # 需要接受响应数据
        self.print_response(resp)

    # 2- 打印请求数据
    def print_request(self, req):
        if req.body == None:
            MsgBody = ""
        else:
            MsgBody = req.body
        self.ui.ResptextBrowser.append(
            '{}\n{}\n{}\n{}'.format('\n------请求数据------',
                                    req.method + ' ' + req.url,
                                    '\n'.join('{}:{}'.format(key, value) for key, value in req.headers.items()),
                                    MsgBody)
        )

    # 3- 打印响应数据
    def print_response(self, resp):
        resp.encoding = 'utf-8'
        self.ui.ResptextBrowser.append(
            '{}\nHTTP/1.1 {}\n{}\n{}'.format('\n------响应数据------',
                                             resp.status_code,
                                             '\n'.join(
                                                 '{}:{}'.format(key, value) for key, value in resp.headers.items()),
                                             resp.text)
        )


app = QApplication([])  # sys.argv 创建一个应用程序
httpClient = HttpClient()  # 创建实例
httpClient.ui.show()
app.exec_()



# -----------------------知识点补充-----------------------
# import requests
# req = requests.Request('get', 'https://www.baidu.com', headers={"name": "sq"})  # 接收到一个请求对象
# prepare = req.prepare()  # 获取请求前数据信息
# print(req)
# print(prepare.body)  # 请求体
# print(prepare.headers)  # 请求头
# s = requests.session()  # 创建个会话对象
# print(s.send(prepare))  # 发送请求---返回值是响应体

接口测试工具.ui
在这里插入图片描述

七、端口扫描工具代码实现
端口扫描工具.py

# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file '端口扫描工具.ui'
##
## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
# 47.96.181.17
from gevent import monkey
monkey.patch_all()
import re
import socket
import time
import gevent
import gevent.pool
from PySide2.QtWidgets import QApplication
# 2- 需要打开一个UI文件
from PySide2.QtCore import QFile
# 3- py代码需要加载ui文件
from PySide2.QtUiTools import QUiLoader  # 需要 加载设计的ui文件


class ScanPort:
    def __init__(self):
        qFile = QFile('端口扫描工具.ui')  # 文件对象
        qFile.open(QFile.ReadOnly)  # 只读方式
        # 6- 加载对象--生成一个ui对象
        self.ui = QUiLoader().load(qFile)
        qFile.close()  # 关闭qfile
        self.ui.pushButton.clicked.connect(self.main)  # 发送请求
        self.ui.clearpushButton.clicked.connect(self.clear)  # 清除扫描结果

    def check_ip(self, ip):
        # 校验ip地址
        ip_address = re.compile(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])')
        if ip_address.match(ip) and len(ip) != 0:
            return True
        else:
            return False

    # 2- 直接使用ip-扫描
    def scan_ip(self, ip):
        # 2- 使用ip判断函数--判断
        if self.check_ip(ip):
            # 进入扫描端口
            self.gevent_scan_port(ip)
        else:
            print('ip格式有误,请检查!')

    def check_domain(self, hostname):
        """
        :param hostname:输入
        :return:是否符合规则
        """
        domainName = re.compile('[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?')
        if domainName.match(hostname) and len(hostname) != 0:
            return True
        else:
            return False

    # 3- 使用域名扫描
    def domain_name_scan(self, domainName):
        # 2- 可做域名判断
        if 'http://' in domainName or 'https://' in domainName:
            domainName = domainName[domainName.find("://") + 3:]  # 取前写后下标
            print("正在解析的域名>>>", domainName)
        # 2- 获取ip
        server_ip = socket.gethostname()
        print(f"该域名{domainName}的ip>>>{server_ip}")
        self.gevent_scan_port(server_ip)

    # 4- 端口扫描函数
    def scan_port(self, ip, port):  # 分段
        # 访问成功是有返回值--是0
        # 使用ip 实现tcp连接
        sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sk.settimeout(0.5)
        try:
            conn = sk.connect_ex((ip, port))  # 有返回值('127.0.0.1', int型)
            if conn == 0:
                print(f'主机:{ip}, 端口:{port}已开放')
                self.ui.scantextBrowser.append(f'主机:{ip}, 端口:{port}已开放')
        except:
            pass
        sk.close()

    # 多线程-扫描
    def gevent_scan_port(self, ip):
        start_time = time.time()  # 开始计时
        g = gevent.pool.Pool(500)  # 限制协程的并发数量
        run_list = []  # 运行的协程
        print(f'主机:{ip},开始扫描......\n')
        self.ui.scantextBrowser.append(f'主机:{ip},开始扫描......\n')
        self.ui.scanprogressBar.setValue(0)
        for port in range(1, 65535 + 1):
            run_list.append(g.spawn(self.scan_port, ip, port))
            if 1 <= port <= 16383:
                self.ui.scanprogressBar.setValue(25)  # 进度条
            elif 16383 < port <= 32766:
                self.ui.scanprogressBar.setValue(50)  # 进度条
            elif 32766 < port <= 49152:
                self.ui.scanprogressBar.setValue(75)  # 进度条
        gevent.joinall(run_list)  # 运行完,主线程退出  阻塞
        self.ui.scanprogressBar.setValue(100)  # 进度条
        end_time = time.time()
        print('端口扫描总共耗时>>>', end_time - start_time)
        print(f'主机:{ip},扫描结束......\n')
        self.ui.scantextBrowser.append(f'主机:{ip},扫描结束......\n')

    # 5- 主入口
    def main(self):
        info = self.ui.IPlineEdit.text()  # 获取IP或域名
        # 2- 接收用户输入
        if self.check_ip(info):
            # ip扫描
            self.scan_ip(info)
        elif self.check_domain(info):
            # 域名扫描
            self.domain_name_scan(info)
        else:
            print('输入有误!')

    def clear(self):
        # 清除扫描结果
        self.ui.scanprogressBar.setValue(0)  # 进度条
        self.ui.scantextBrowser.clear()


app = QApplication([])  # sys.argv 创建一个应用程序
ScanPort = ScanPort()  # 创建实例
ScanPort.ui.show()
app.exec_()

端口扫描工具.ui
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每 天 早 睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值