前言
最近app测试比较多,每次都得手动输入日志tag,手动安装,测完又去卸载,太麻烦。就搞了小工具使用。
效果预览
每次测试完成,点击退出本次测试,就直接卸载了,usb插下一个手机又可以继续测了。
使用了uiautomator2 ,PySimpleGUI和 Pyinstaller打包,没什么太难的东西,,只简单使用了这些,没深入复杂的使用。
源代码分享
import subprocess
import PySimpleGUI as sg
import time
import uiautomator2 as u2
class DeviceManager:
"""设备管理器"""
def __init__(self):
self.device = None
self.connect_device()
def connect_device(self):
"""连接设备,如果失败会重试"""
try:
self.device = u2.connect()
self.device.implicitly_wait(5)
return True
except Exception as e:
print(f"设备连接失败: {e}")
def ensure_connected(self):
"""确保设备已连接"""
try:
# 尝试执行一个简单的命令来检查连接状态
self.device.info
return True
except:
return self.connect_device()
def install_app(self, file_path):
"""安装应用并返回包名"""
new_package = ''
if not self.ensure_connected():
return None
try:
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 None
except Exception as e:
print(f'安装应用失败: {e}')
return None
finally:
window.TKroot.title(f'{new_package}测试中...')
def uninstall_app(self, package_name):
"""卸载应用"""
if not package_name:
return
if not self.ensure_connected():
return
try:
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 = True
def 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}"
activate
id of window 1
end 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} 已断开,正在重连...")
break
time.sleep(5)
except Exception as e:
print(f"启动日志进程失败: {e}, 正在重试...")
if not self.is_running:
break
time.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 windows
if id of w is {window_id} then
close w
end if
end repeat
end 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"
try
repeat with w in windows
if id of w is {window_id} then
do script "exit" in w
close w
end if
end repeat
end try
end 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)
# break
elif 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}"
activate
id 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()