diff --git a/README.md b/README.md index c13b2fe..bec37d5 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,30 @@ AndroidTestScripts Android测试中常用到的脚本 -###主要脚本功能 +### 主要脚本功能 批量安装应用(支持以中文命名的 apk)、批量卸载、截屏、录制视频、获取当前应用的 apk 文件、包名、Activity 名等。
+### 2019.05.29 +多设备的时候列表显示device ID,修改为显示设备model名 -###2016.7.19 +![device_id](image/device_name_list.png) + +### 2018.05.01 +修改 `screenrecord.py` ,原有脚本有时候会出现录制完的视频在 pull 到本地的时候卡死。修改后的脚本需要输入录制时间。 + + +### 2016.07.19 增加部分python脚本对多设备的支持: ![device_id](image/device_id.png) -###2016.04.22 +### 2016.04.22 增加 `fps.py`,获取测试界面的 `fps`、`jankniess`。 使用方法:按照提示输入参数,测试过程中操作界面,最终数据结果存放于 `fps_data` 目录下,csv 格式。 如有错误,请指出! -####demo: +#### demo: 测试界面: @@ -33,7 +41,7 @@ cmd 界面: ![fps_chart](image/fps_chart.png) -###2016.01.21 +### 2016.01.21 增加 `logcat.py`,windows 中在 cmd 里面运行 logcat 命令,会给输出的日志内容根据优先级添加颜色。使用前提是已配置 adb 及 python 的环境变量,在 cmd 里面可以直接运行 adb 命令和python 脚本。 用法: 将`logcat.py` 配置到环境变量里面,使得可以在 cmd 中可以直接执行 logcat 命令。参数与 `adb logcat` 的一样。例如: @@ -49,10 +57,10 @@ logcat 执行后: 当要使用重定向时,请使用 `adb logcat`. -###2015.06.02 +### 2015.06.02 增加 `get_app_crash_log.py` 与 `getAppCrashLog.sh`, 应用发生 crash ,未及时从 logcat 获取到有效 log 时,可通过该脚本获取 log -###2015.05.30 +### 2015.05.30 增加 `get_app_permission.py`,获取设备当前应用的权限详情,windows 下会将结果写入 `permission.txt` 文件中,其他系统打印在控制台: ``` @@ -79,13 +87,13 @@ android.permission.MODIFY_AUDIO_SETTINGS: 允许应用程序修改整个系统的音频设置,如音量和路由。 ``` -###2015.02.12 +### 2015.02.12 因日常工作需要,增加备份设备中安装的第三方应用的脚本 `backup_app.py`。(区别于adb backup命令,只备份apk)
-###2015.01.31 +### 2015.01.31 修改 `screenrecord.py` 中的默认录制时间,默认最长录制时间为 180 秒
-###2015.01.29 +### 2015.01.29 新增脚本 `get_cpu_mem_info.py`,获取设备当前运行的应用的 cpu、memory 信息,默认 top times 取值为20次,可自己修改脚本中的该参数 脚本运行需要安装pychartdir模块,安装方法请参考 [http://blog.csdn.net/gb112211/article/details/43272049](http://blog.csdn.net/gb112211/article/details/43272049 "python pychartdir模块的安装及使用")
@@ -93,10 +101,10 @@ android.permission.MODIFY_AUDIO_SETTINGS: ![image](image/cpu_mem_info.png "chart" ) -###2015.01.28 +### 2015.01.28 修改了设备状态判断的代码(脚本自己都曾使用OK,如有问题,可以QQ联系:274925460)
-###2015.01.26 +### 2015.01.26 1. 改写 python 分类中的脚本结构,将大部分方法分装进了 scriptUtils 包中的 utils 模块中
2. 新增 `screenrecord.py`(录制视频,Android4.4新增功能)
diff --git a/image/device_name_list.png b/image/device_name_list.png new file mode 100644 index 0000000..27f456a Binary files /dev/null and b/image/device_name_list.png differ diff --git a/python/installApp.py b/python/installApp.py new file mode 100644 index 0000000..5e975cd --- /dev/null +++ b/python/installApp.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +#coding=utf-8 + +''' +Created on 2019/5/30 10:24 +@author: rikixu +''' + +from scriptUtils import utils + + +def install(apkPath): + print (utils.adb("install -r %s" %apkPath).stdout.read()) + + +if __name__ == "__main__": + apkPath = raw_input("apk path:") + install(apkPath) \ No newline at end of file diff --git a/python/screenrecord.py b/python/screenrecord.py index fdf84fc..f556187 100644 --- a/python/screenrecord.py +++ b/python/screenrecord.py @@ -14,27 +14,27 @@ from scriptUtils import utils -#需要Android4.4及4.4以上版本,运行脚本后可录制设备上的操作,默认使用手机分辨率,时间3min。手动按Enter结束录制。 +#需要Android4.4及4.4以上版本,运行脚本后可录制设备上的操作,默认使用手机分辨率,手动设置录制时间。 #录制结果存放于当前目录下的video目录下 PATH = lambda p: os.path.abspath(p) def record(): - utils.shell("screenrecord /data/local/tmp/video.mp4") - input_key = raw_input("Please press the Enter key to stop recording:\n") - if input_key == "": - utils.adb("kill-server") - - print "Get Video file..." - utils.adb("start-server") - time.sleep(1.5) - - path = PATH("%s/video" %os.getcwd()) - if not os.path.isdir(path): - os.makedirs(path) - - utils.adb("pull /data/local/tmp/video.mp4 %s" %PATH("%s/%s.mp4" %(path, utils.timestamp()))).wait() - + utils.shell("rm -f /data/local/tmp/video.mp4") + limit_time = raw_input("Please set the maximum recording time, in seconds. Maximum is 180.\n") + if limit_time == "": + utils.shell("screenrecord --time-limit 180 /data/local/tmp/video.mp4") + try: + _limit_time = int(limit_time) + 1 + except: + record() + if 0 < _limit_time <= 180: + utils.shell("screenrecord --time-limit %s /data/local/tmp/video.mp4" %limit_time).wait() + else: + print "Please set again!" + record() + + if __name__ == "__main__": sdk = string.atoi(utils.shell("getprop ro.build.version.sdk").stdout.read()) if sdk < 19: @@ -42,4 +42,12 @@ def record(): sys.exit(0) else: record() + print "Get Video file..." + time.sleep(3) + + path = PATH("%s/video" %os.getcwd()) + if not os.path.isdir(path): + os.makedirs(path) + + utils.adb("pull /data/local/tmp/video.mp4 %s" %PATH("%s/%s.mp4" %(path, utils.timestamp()))) print "Completed" diff --git a/python/scriptUtils/utils.py b/python/scriptUtils/utils.py index d0e145a..ba99689 100644 --- a/python/scriptUtils/utils.py +++ b/python/scriptUtils/utils.py @@ -11,21 +11,21 @@ import re import subprocess import time -import Tkinter as tk +import Tkinter as tk import ttk import exception serialno_num = "" -#判断系统类型,windows使用findstr,linux使用grep +# 判断系统类型,windows使用findstr,linux使用grep system = platform.system() if system is "Windows": find_util = "findstr" else: find_util = "grep" -#判断是否设置环境变量ANDROID_HOME +# 判断是否设置环境变量ANDROID_HOME if "ANDROID_HOME" in os.environ: if system == "Windows": command = os.path.join(os.environ["ANDROID_HOME"], "platform-tools", "adb.exe") @@ -39,22 +39,30 @@ def get_screen_size(window): return window.winfo_screenwidth(),window.winfo_screenheight() + def get_window_size(window): return window.winfo_reqwidth(),window.winfo_reqheight() + def center_window(root, width, height): screenwidth = root.winfo_screenwidth() screenheight = root.winfo_screenheight() size = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2) root.geometry(size) + class Window(object): device_id = "" device_id_list = [] + device_name_list = [] + device_name_dict = {} root = None box = None + def __init__(self, device_id_list, root): self.device_id_list = device_id_list + self.device_name_dict = get_device_name_dict(self.device_id_list) + self.get_device_name_list() self.device_id = device_id_list[0] self.root = root self.box = None @@ -65,7 +73,8 @@ def show_window(self): self.root.maxsize(600, 400) self.root.minsize(300, 240) - options = self.device_id_list + # options = self.device_id_list + options = self.device_name_list self.box = ttk.Combobox(values=options) self.box.current(0) self.box.pack(expand = tk.YES) @@ -74,22 +83,29 @@ def show_window(self): self.root.mainloop() - def select(self, event=None): - self.device_id = self.box.selection_get() + for key, value in self.device_name_dict.iteritems(): + if value == self.box.selection_get(): + self.device_id = key + # self.device_id = self.box.selection_get() def ok(self): global serialno_num serialno_num = self.device_id self.root.destroy() -#adb命令 + def get_device_name_list(self): + for id in self.device_id_list: + self.device_name_list.append(self.device_name_dict.get(id)) + + +# adb命令 def adb(args): global serialno_num if serialno_num == "": devices = get_device_list() if len(devices) == 1: - #global serialno_num + # global serialno_num serialno_num = devices[0] else: root = tk.Tk() @@ -116,7 +132,8 @@ def shell(args): def get_state(): return os.popen("adb -s %s get-state" %serialno_num).read().strip() -#获取对应包名的pid + +# 获取对应包名的pid def get_app_pid(pkg_name): if system is "Windows": string = shell("ps | findstr %s$" %pkg_name).stdout.read() @@ -132,7 +149,8 @@ def get_app_pid(pkg_name): return pattern.findall(" ".join(result))[0] -#杀掉对应包名的进程 + +# 杀掉对应包名的进程 def kill_process(pkg_name): pid = get_app_pid(pkg_name) @@ -141,28 +159,35 @@ def kill_process(pkg_name): if result != "": raise exception.SriptException("Operation not permitted or No such process") -#获取设备上当前应用的包名与activity + +# 获取设备上当前应用的包名与activity def get_focused_package_and_activity(): pattern = re.compile(r"[a-zA-Z0-9\.]+/.[a-zA-Z0-9\.]+") - #out = shell("dumpsys window w | %s \/ | %s name=" %(find_util, find_util)).stdout.read() + tmp = shell("dumpsys activity | %s mFocusedActivity" %find_util).stdout.read() + name = "" + try: + name = pattern.findall(tmp)[0] + except: + tmp = shell("dumpsys window w | %s \/ | %s name=" %(find_util, find_util)).stdout.read() + name = pattern.findall(tmp)[0] + return name - #return pattern.findall(out)[0] - str = shell("dumpsys activity | %s mFocusedActivity" %find_util).stdout.read() - #return shell("dumpsys activity | %s mFocusedActivity" %find_util).stdout.read().split()[-1][:-1] - return pattern.findall(str)[0] -#获取当前应用的包名 +# 获取当前应用的包名 def get_current_package_name(): return get_focused_package_and_activity().split("/")[0] -#获取当前设备的activity + +# 获取当前设备的activity def get_current_activity(): return get_focused_package_and_activity().split("/")[-1] -#时间戳 + +# 时间戳 def timestamp(): return time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time())) + def get_device_list(): devices = [] result = subprocess.Popen("adb devices", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines() @@ -173,12 +198,23 @@ def get_device_list(): else: break return devices + +def get_device_name_dict(devices): + device_dict = {} + if not devices: + return + + for device in devices: + cmd = "adb -s %s shell getprop ro.product.model" %device + device_name = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readline().strip() + device_dict[device] = device_name + return device_dict -#连接设备 +# 连接设备 # adb("kill-server").wait() # adb("start-server").wait() -adb("wait-for-device") +adb("wait-for-device").wait() if get_state() != "device": adb("kill-server").wait() @@ -189,4 +225,4 @@ def get_device_list(): if __name__ == "__main__": - pass + print get_focused_package_and_activity() diff --git a/shell/batch_uninstall.sh b/shell/batch_uninstall.sh index 3a4630c..29bf381 100644 --- a/shell/batch_uninstall.sh +++ b/shell/batch_uninstall.sh @@ -1,6 +1,6 @@ #!/bin/sh -adb shell wait-for-device +adb wait-for-device echo start remove... for package in `adb shell pm list package -3 | cut -d : -f 2 | tr -d "\r"`