App测试小工具
前言
最近app测试比较多,每次都得手动输入日志tag,手动安装,测完又去卸载,太麻烦。就搞了小工具使用。
效果预览
每次测试完成,点击退出本次测试,就直接卸载了,usb插下一个手机又可以继续测了。
使用了uiautomator2 ,PySimpleGUI和 Pyinstaller打包,没什么太难的东西,,只简单使用了这些,没深入复杂的使用。
源代码分享
import subprocess
import PySimpleGUI as sg
import time
import uiautomator2 as u2class DeviceManager:"""设备管理器"""def __init__(self):self.device = Noneself.connect_device()def connect_device(self):"""连接设备,如果失败会重试"""try:self.device = u2.connect()self.device.implicitly_wait(5)return Trueexcept Exception as e:print(f"设备连接失败: {e}")def ensure_connected(self):"""确保设备已连接"""try:# 尝试执行一个简单的命令来检查连接状态self.device.inforeturn Trueexcept:return self.connect_device()def install_app(self, file_path):"""安装应用并返回包名"""new_package = ''if not self.ensure_connected():return Nonetry:installed_before = set(self.device.app_list())self.device.app_install(file_path)installed_after = set(self.device.app_list())new_package = list(installed_after - installed_before)return new_package[0] if new_package else Noneexcept Exception as e:print(f'安装应用失败: {e}')return Nonefinally:window.TKroot.title(f'{new_package}测试中...')def uninstall_app(self, package_name):"""卸载应用"""if not package_name:returnif not self.ensure_connected():returntry:if package_name in self.device.app_list():self.device.app_uninstall(package_name)print(f"成功卸载应用: {package_name}")else:print(f"应用 {package_name} 未安装")except Exception as e:print(f"卸载应用失败: {e}")class LogcatManager:"""日志管理器"""def __init__(self):self.processes = []self.window_ids = []self.is_running = Truedef start_logcat(self, tag):"""启动单个logcat进程"""while self.is_running:try:apple_script = f'''tell application "Terminal"set newWindow to do script "adb logcat -s {tag}"activateid of window 1end tell'''window_id = subprocess.check_output(['osascript', '-e', apple_script]).decode().strip()self.window_ids.append(window_id)# 检查logcat进程是否存在while self.is_running:result = subprocess.run(['pgrep', '-f', f'adb logcat -s {tag}'], capture_output=True)if result.returncode != 0:print(f"日志进程 {tag} 已断开,正在重连...")breaktime.sleep(5)except Exception as e:print(f"启动日志进程失败: {e}, 正在重试...")if not self.is_running:breaktime.sleep(3)def stop_all(self):"""停止所有日志进程"""self.is_running = False# 关闭所有Terminal窗口for window_id in self.window_ids:close_script = f'''tell application "Terminal"repeat with w in windowsif id of w is {window_id} thenclose wend ifend repeatend tell'''subprocess.run(['osascript', '-e', close_script])self.window_ids = []d = DeviceManager()
logcat_mgr = LogcatManager()# 定义布局
layout = [[sg.Text('选择apk文件')],[sg.InputText(key='-FILE-'), sg.FileBrowse(button_text='选择apk文件')],[sg.Text('需要监控的日志,以英文逗号分割(tag1,tag2)')],[sg.InputText(key='-TAG-')],[sg.Button('安装并监控'), sg.Button('退出本次测试'), sg.Text("如需退出程序,点击左上角'x'")],
]with open('./logo.bin', 'rb') as f:data = f.read()
# 创建窗口
window = sg.Window('外广安装apk', layout, icon=data)# 安装包名
package_name = ''terminal_window_ids = []def install_app(file_path):window.TKroot.title('apk安装中...')window.refresh()return d.install_app(file_path)# 事件循环
while True:event, values = window.read()if event == '退出本次测试':window.TKroot.title('外广测试apk')# 清空文件输入框和标签输入框# window['-FILE-'].update('')# window['-TAG-'].update('')# 只关闭本次打开的Terminal窗口for window_id in terminal_window_ids:close_script = f'''tell application "Terminal"tryrepeat with w in windowsif id of w is {window_id} thendo script "exit" in wclose wend ifend repeatend tryend tell'''try:subprocess.run(['osascript', '-e', close_script], check=True)except subprocess.CalledProcessError as e:print(f"关闭终端窗口失败: {e}")# 确保所有相关的 adb logcat 进程都被终止try:subprocess.run(['pkill', '-f', 'adb logcat'], check=False)except Exception as e:print(f"终止 adb logcat 进程失败: {e}")# 卸载安装的应用if package_name:d.uninstall_app(package_name)# breakelif event == '安装并监控':file_path = values['-FILE-']if file_path:# 安装应用并获取包名package_name = install_app(file_path)print('安装成功时间:', time.strftime('%H:%M:%S', time.localtime()))# 启动日志监控tags = values['-TAG-'].split(',')for tag in tags:# 打开新终端窗口,设置标题并执行 adb logcat 命令apple_script = f'''tell application "Terminal"set newWindow to do script "adb logcat -s {tag}"set current settings of newWindow to settings set "Basic"set custom title of newWindow to "Log Monitor - {tag}"activateid of (first window whose selected tab is newWindow)end tell'''window_id = subprocess.check_output(['osascript', '-e', apple_script]).decode().strip()terminal_window_ids.append(window_id)else:print('请选择apk文件')elif event == sg.WINDOW_CLOSED:break
# 关闭窗口
window.close()