一、需求分析
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