├── changelog ├── performance ├── __init__.py ├── config │ ├── .DS_Store │ └── __init__.py ├── img │ └── mail.png ├── libs │ ├── .DS_Store │ ├── __init__.py │ ├── base.py │ ├── device_monitor.py │ ├── mail.py │ └── set_config.py ├── log │ └── .DS_Store └── monkey │ ├── .DS_Store │ ├── __init__.py │ ├── monkey.py │ ├── monkey_server.py │ ├── monkey_stop.py │ └── monkeylog │ └── .DS_Store ├── readme.md ├── user_config └── default.conf └── version /changelog: -------------------------------------------------------------------------------- 1 | 2 | version 1.1 3 | 1. 支持配置文件 4 | 5 | version 1.0 6 | 1. 完全自动:只需要负责连接设备 7 | 2. 支持多个设备 8 | 3. 支持随时断开设备、插入新设备,每5s定时检测设备自动运行 9 | 4. 崩溃后,发送邮件,邮件内容:执行时长、crash log 10 | 5. 支持Windows、Mac系统 -------------------------------------------------------------------------------- /performance/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/__init__.py -------------------------------------------------------------------------------- /performance/config/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/config/.DS_Store -------------------------------------------------------------------------------- /performance/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/config/__init__.py -------------------------------------------------------------------------------- /performance/img/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/img/mail.png -------------------------------------------------------------------------------- /performance/libs/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/libs/.DS_Store -------------------------------------------------------------------------------- /performance/libs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/libs/__init__.py -------------------------------------------------------------------------------- /performance/libs/base.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import platform 6 | import commands 7 | import sys 8 | import time 9 | import logging 10 | import subprocess 11 | import traceback 12 | 13 | if __name__ == '__main__': 14 | project_dir = os.path.split(os.getcwd()) 15 | project_dir = os.path.split(project_dir[0]) 16 | sys.path.append(project_dir[0]) 17 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 18 | 19 | from performance.config.config import Config 20 | 21 | reload(sys) 22 | sys.setdefaultencoding('utf-8') 23 | 24 | config = Config() 25 | adb = config.adb 26 | 27 | def start_adb(): 28 | cmd = "%s devices" % Config.adb 29 | if platform.system() == 'Windows': 30 | subprocess.check_output(cmd, shell=True) 31 | else: 32 | commands.getstatusoutput(cmd) 33 | time.sleep(2) 34 | 35 | def get_info_from_mac(): 36 | '''返回 device id 和 device model''' 37 | device_dict = {} 38 | get_device_id_cmd = "%s devices | grep '\tdevice'" % adb 39 | (status, output) = commands.getstatusoutput(get_device_id_cmd) 40 | # logging.info(output) 41 | if output == '': 42 | logging.info('All device lost') 43 | else: 44 | output = output.split("\n") 45 | # logging.info(output) 46 | device_id_list = [] 47 | for device_id in output: 48 | device_id = device_id.replace("\tdevice", "") 49 | device_id_list.append(device_id) 50 | # logging.info(device_id_list) 51 | 52 | for device_id in device_id_list: 53 | device_model = "" 54 | get_device_model_cmd = "%s -s %s shell getprop ro.product.model" % (adb, device_id) 55 | # logging.info(get_device_model_cmd) 56 | (status, output) = commands.getstatusoutput(get_device_model_cmd) 57 | # logging.info("'%s'" %output) 58 | output = output.strip("\r") # 去除行尾的换行光标 59 | output = output.split(" ") 60 | for i in output: 61 | device_model += i 62 | # logging.info("'%s'" %device_model) 63 | device_dict.update({device_model: device_id}) 64 | logging.debug("get the device info: %s" % device_dict) 65 | return device_dict 66 | 67 | def get_info_from_win(): 68 | '''返回 device model 和 device id''' 69 | device_dict = {} 70 | get_device_id_cmd = "%s devices | findstr /e device" % adb # /e 对一行的结尾进行匹配 71 | try: 72 | output = subprocess.check_output(get_device_id_cmd, shell=True) 73 | logging.debug('connected devices:\r%s' % output) 74 | except Exception: 75 | # traceback.print_exc() 76 | logging.info("All device lost") 77 | output = None 78 | if output is not None: 79 | output = output.split("\n") 80 | logging.debug('split connect devices id: %s' % output) 81 | device_id_list = [] 82 | for device_id in output: 83 | if 'device' in device_id: 84 | logging.debug('get device: %s' % device_id) 85 | device_id = device_id.replace("\tdevice\r", "") 86 | device_id_list.append(device_id) 87 | logging.debug('got devices id: %s' % device_id_list) 88 | 89 | for device_id in device_id_list: 90 | device_model = "" 91 | get_device_model_cmd = "%s -s %s shell getprop ro.product.model" % (adb, device_id) 92 | # logging.info(get_device_model_cmd) 93 | try: 94 | output_model = subprocess.check_output(get_device_model_cmd, shell=True) 95 | logging.debug("'%s'" % output_model) 96 | except Exception: 97 | logging.error('get device model error') 98 | traceback.print_exc() 99 | output_model = None 100 | if output_model is not None: 101 | output_model = output_model.strip("\r\r\n") # 去除行尾的换行光标 102 | logging.debug(output_model) 103 | output_model = output_model.split(' ') 104 | for i in output_model: 105 | device_model += i 106 | # logging.info("'%s'" %device_model) 107 | device_dict.update({device_model: device_id}) 108 | logging.debug("get the device info: %s" % device_dict) 109 | return device_dict 110 | 111 | def get_device_info(): 112 | if platform.system() == "Darwin": 113 | return get_info_from_mac() 114 | elif platform.system() == "Windows": 115 | return get_info_from_win() 116 | 117 | if __name__ == '__main__': 118 | get_device_info() 119 | pass 120 | 121 | -------------------------------------------------------------------------------- /performance/libs/device_monitor.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | # coding: utf-8 3 | 4 | import time 5 | import os 6 | import sys 7 | import logging 8 | 9 | if __name__ == '__main__': 10 | project_dir = os.path.split(os.getcwd()) 11 | project_dir = os.path.split(project_dir[0]) 12 | sys.path.append(project_dir[0]) 13 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 14 | 15 | from performance.config.config import Config 16 | from performance.libs.base import get_device_info, start_adb 17 | from performance.monkey.monkey import create_threads_monkey 18 | 19 | def monitor_device(): 20 | start_adb() 21 | while True: 22 | # logging.info("monitor_device") 23 | time.sleep(5) 24 | current_device_dict = {} 25 | new_device_dict = {} 26 | current_device_dict = get_device_info() 27 | logging.debug('current device dict: %s' % current_device_dict) 28 | logging.debug('Config.device_dict is %s' % Config.device_dict) 29 | if current_device_dict != Config.device_dict: 30 | for device_model, device_id in current_device_dict.iteritems(): 31 | if device_model not in Config.device_dict: 32 | new_device_dict.update({device_model: device_id}) 33 | 34 | if new_device_dict != {}: 35 | logging.debug('new device dict is: %s' % new_device_dict) 36 | else: 37 | logging.info('device lost') 38 | Config.device_dict = current_device_dict 39 | create_threads_monkey(new_device_dict) 40 | # restart_threads() 41 | 42 | if __name__ == '__main__': 43 | pass 44 | 45 | 46 | -------------------------------------------------------------------------------- /performance/libs/mail.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from email.mime.text import MIMEText 5 | import time 6 | import smtplib 7 | import logging 8 | import traceback 9 | import os 10 | import sys 11 | 12 | if __name__ == '__main__': 13 | project_dir = os.path.split(os.getcwd()) 14 | project_dir = os.path.split(project_dir[0]) 15 | sys.path.append(project_dir[0]) 16 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 17 | 18 | from performance.config.config import Config 19 | 20 | config = Config() 21 | 22 | 23 | class SendMail(): 24 | ''' 25 | send email 26 | ''' 27 | 28 | def __init__(self): 29 | self.mail_host = config.mail_host # 设置服务器 30 | self.mail_user = config.mail_user # 用户名 31 | self.mail_pass = config.mail_pass # 密码 32 | 33 | self.str_date = time.strftime('%Y-%m-%d %H:%M', time.localtime(time.time())) 34 | 35 | def send_mail(self, to_list, content): 36 | me = " Automation" + "<" + self.mail_user + ">" 37 | msg = MIMEText(content, _subtype='plain', _charset='utf-8') 38 | msg['Subject'] = config.mail_pre_title + self.str_date 39 | msg['From'] = me 40 | msg['To'] = ";".join(to_list) 41 | try: 42 | server = smtplib.SMTP() 43 | server.connect(self.mail_host) 44 | server.login(self.mail_user, self.mail_pass) 45 | server.sendmail(me, to_list, msg.as_string()) 46 | server.close() 47 | logging.info("发送成功") 48 | return True 49 | except Exception: 50 | traceback.print_exc() 51 | logging.info("发送失败") 52 | return False 53 | 54 | if __name__ == '__main__': 55 | 56 | # 测试邮箱是否配置成功 57 | mail = SendMail() 58 | mail.send_mail(config.mail_to_list, 'abcd') 59 | -------------------------------------------------------------------------------- /performance/libs/set_config.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import os 5 | import sys 6 | import logging 7 | import traceback 8 | import ConfigParser 9 | 10 | if __name__ == '__main__': 11 | project_dir = os.path.split(os.getcwd()) 12 | project_dir = os.path.split(project_dir[0]) 13 | sys.path.append(project_dir[0]) 14 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 15 | 16 | from performance.config.config import Config 17 | 18 | reload(sys) 19 | sys.setdefaultencoding('utf-8') 20 | 21 | 22 | def set_custom_config(config_file): 23 | if os.path.exists(config_file) is True: 24 | config_parser = ConfigParser.ConfigParser() 25 | config_parser.read(config_file) 26 | Config.package_name = config_parser.get('config', 'package_name') 27 | Config.adb_location = config_parser.get('config', 'adb_location') 28 | Config.adb = config_parser.get('config', 'adb_location') 29 | Config.mail_host = config_parser.get('config', 'mail_host') 30 | Config.mail_user = config_parser.get('config', 'mail_user') 31 | Config.mail_pass = config_parser.get('config', 'mail_pass') 32 | Config.mail_to_list = config_parser.options('mail_to_list') 33 | 34 | monkey_parameters_list = config_parser.items('monkey_parameters') 35 | monkey_parameters = "" 36 | for i in monkey_parameters_list: 37 | monkey_parameters += "%s %s " % (i[0], i[1]) 38 | Config.monkey_parameters = monkey_parameters 39 | -------------------------------------------------------------------------------- /performance/log/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/log/.DS_Store -------------------------------------------------------------------------------- /performance/monkey/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/monkey/.DS_Store -------------------------------------------------------------------------------- /performance/monkey/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/monkey/__init__.py -------------------------------------------------------------------------------- /performance/monkey/monkey.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | # coding: utf-8 3 | 4 | import time 5 | import commands 6 | import os 7 | import sys 8 | import logging 9 | import threading 10 | import platform 11 | import subprocess 12 | import traceback 13 | 14 | if __name__ == '__main__': 15 | project_dir = os.path.split(os.getcwd()) 16 | project_dir = os.path.split(project_dir[0]) 17 | sys.path.append(project_dir[0]) 18 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 19 | 20 | from performance.config.config import Config 21 | from performance.libs.mail import SendMail 22 | from performance.monkey.monkey_stop import stop_monkey 23 | 24 | wkdir = os.getcwd() 25 | adb = Config.adb 26 | package_name = Config.package_name 27 | monkey_seed = Config.monkey_seed 28 | monkey_parameters = Config.monkey_parameters 29 | 30 | 31 | def main(device_id, device_model): 32 | try: 33 | stop_monkey(device_id, device_model) 34 | 35 | log_file_name = generate_log_file_name(device_model) 36 | log_file_name_with_location = generate_log_file_name_with_location(device_model) 37 | monkey_duration = start_monkey(adb, device_id, device_model, monkey_seed, monkey_parameters, package_name) 38 | capture_screen(device_id, log_file_name, log_file_name_with_location, monkey_duration) 39 | mail_content = deal_with_log(log_file_name_with_location, monkey_duration) 40 | mail = SendMail() 41 | if mail_content == '': 42 | mail_content = 'No crash happened' 43 | mail.send_mail(Config.mail_to_list, mail_content) 44 | reboot_device(device_id, device_model) 45 | except Exception: 46 | traceback.print_exc() 47 | 48 | 49 | def get_apk_name(): 50 | abspath = os.path.abspath(__file__) 51 | current_location = os.path.split(abspath)[0] 52 | files_in_current_location = os.listdir(current_location) 53 | 54 | for i in files_in_current_location: 55 | if 'apk' in i: 56 | apk_name = i 57 | return apk_name 58 | 59 | # def reinstall(): 60 | # # uninstall & install app 61 | # location_apk=os.path.join(current_location, apk_name) 62 | # print location_apk 63 | 64 | # print '\runinstalling...' 65 | # output = subprocess.check_output(adb + '-s ' + device_id + ' uninstall ' + package_name, shell=True) 66 | # print output 67 | # print '\rinstalling...' 68 | # output = subprocess.check_output(adb + '-s ' + device_id + ' install ' + location_apk, shell=True) 69 | # print output 70 | 71 | # print 'reboot device...' 72 | # output = subprocess.check_output(adb + '-s ' + device_id + ' reboot', shell=True) 73 | # count_time = 0 74 | # for i in range(60): 75 | # time.sleep(1) 76 | # count_time += 1 77 | # print count_time, 78 | # print 79 | 80 | 81 | def generate_log_file_name(device_model): 82 | # 生成 crash log 名字 83 | current_time = time.strftime("%m-%d~%H-%M-%S") 84 | log_file_name = device_model + '_' + current_time 85 | return log_file_name 86 | 87 | 88 | def generate_log_file_name_with_location(device_model): 89 | # 获取当前 Log 存储路径 90 | location_log = os.path.join(wkdir, 'performance', 'monkey', 'monkeylog') 91 | current_date = time.strftime("%Y-%m-%d") 92 | current_date = os.path.join(location_log, current_date) 93 | if os.path.exists(current_date) is False: 94 | os.mkdir(current_date) 95 | log_file_name = generate_log_file_name(device_model) 96 | log_file_name_with_location = os.path.join(current_date, log_file_name) 97 | return log_file_name_with_location 98 | 99 | 100 | def start_monkey(adb, device_id, device_model, monkey_seed, monkey_parameters, package_name): 101 | logging.info("start monkey with %s" % device_model) 102 | log_file_name_with_location = generate_log_file_name_with_location(device_model) 103 | monkey_start_time = time.time() 104 | cmd_monkey = "%s -s %s shell monkey -s %s -p %s %s > %s.txt" % ( 105 | adb, device_id, monkey_seed, package_name, monkey_parameters, log_file_name_with_location) 106 | # cmd_monkey = "%s -s %s shell monkey -s %s -p %s --pct-touch 10 --pct-motion 10 --pct-appswitch 80 -v 400000000 > %s.txt" %(adb, device_id, monkey_seed, package_name, log_file_name_with_location) 107 | if platform.system() == "Darwin": 108 | logging.info("Monkey cmd: %s" % cmd_monkey) 109 | status, output = commands.getstatusoutput(cmd_monkey) 110 | elif platform.system() == "Windows": 111 | logging.info("Monkey cmd: %s" % cmd_monkey) 112 | output = subprocess.check_output(cmd_monkey, shell=True) 113 | logging.info("monkey end with %s" % device_model) 114 | monkey_end_time = time.time() 115 | monkey_duration = round((monkey_end_time - monkey_start_time) / 3600, 2) 116 | return str(monkey_duration) 117 | 118 | 119 | def capture_screen(device_id, log_file_name, log_file_name_with_location, monkey_duration): 120 | logging.info("capture screen") 121 | cmd_capture = "%s -s %s shell screencap -p /sdcard/%s.png" % (adb, device_id, log_file_name) 122 | status, output = commands.getstatusoutput(cmd_capture) 123 | if output == "": 124 | cmd_pull_screenshot = "%s -s %s pull /sdcard/%s.png %s.png" % ( 125 | adb, device_id, log_file_name, log_file_name_with_location) 126 | status, output = commands.getstatusoutput(cmd_pull_screenshot) 127 | logging.info(output) 128 | # rename log file 129 | if output == "": 130 | log_file_name_location_final = log_file_name_with_location + '_' + monkey_duration 131 | os.rename(log_file_name_with_location + '.png', log_file_name_location_final + '.png') 132 | 133 | 134 | def deal_with_log(log_file_name_with_location, monkey_duration): 135 | # analyze with log: 136 | logging.info("deal_with_log") 137 | f_full_log = open(log_file_name_with_location + '.txt', 'r') 138 | full_log = f_full_log.readlines() 139 | f_full_log.close() 140 | full_log_lines_number = len(full_log) 141 | anr = '// NOT RESPONDING: ' + package_name + ' ' 142 | exception = '// CRASH: ' + package_name + ' ' 143 | mail_content = '' 144 | for i in xrange(full_log_lines_number): 145 | if (exception in full_log[i]) | (anr in full_log[i]): 146 | f_crash_log = open(log_file_name_with_location + '.txt', 'r') 147 | f_crash_log.close() 148 | for j in range(i, full_log_lines_number): 149 | mail_content = mail_content + full_log[j] + '\r' 150 | # f_crash_log = open(log_file_name_with_location + '.txt', 'a+') 151 | # f_crash_log.writelines(full_log[j]) 152 | # f_crash_log.close() 153 | break 154 | if mail_content == "": 155 | return mail_content 156 | else: 157 | # rename log file 158 | log_file_name_location_final = log_file_name_with_location + ' ' + monkey_duration + "hour" 159 | tmp = log_file_name_with_location.split('/') 160 | # logging.info(tmp) 161 | log_file_name = tmp[-1] 162 | mail_content = log_file_name + '_' + monkey_duration + "hour" + '\r\r' + mail_content 163 | os.rename(log_file_name_with_location + '.txt', log_file_name_location_final + '.txt') 164 | return mail_content 165 | 166 | 167 | def reboot_device(device_id, device_model): 168 | if platform.system() == "Darwin": 169 | logging.info("Reboot %s" % device_model) 170 | status, output = commands.getstatusoutput(adb + ' -s ' + device_id + ' reboot') 171 | elif platform.system() == "Windows": 172 | subprocess.check_output("%s -s %s reboot" % (adb, device_id), shell=True) 173 | 174 | 175 | class MonkeyThread(threading.Thread): 176 | def __init__(self, device_id, device_model): 177 | threading.Thread.__init__(self) 178 | self.thread_stop = False 179 | self.device_id = device_id 180 | self.device_model = device_model 181 | 182 | def run(self): 183 | time.sleep(6) 184 | main(self.device_id, self.device_model) 185 | 186 | def create_threads_monkey(device_dict): 187 | thread_instances = [] 188 | if device_dict != {}: 189 | logging.info('changed device: %s' % device_dict) 190 | for model_device, id_device in device_dict.iteritems(): 191 | device_model = model_device 192 | device_id = id_device 193 | instance = MonkeyThread(device_id, device_model) 194 | thread_instances.append(instance) 195 | for instance in thread_instances: 196 | instance.start() 197 | 198 | if __name__ == '__main__': 199 | pass 200 | 201 | -------------------------------------------------------------------------------- /performance/monkey/monkey_server.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | # coding: utf-8 3 | 4 | import os 5 | import sys 6 | import logging 7 | import traceback 8 | 9 | project_dir = os.path.split(sys.path[0]) 10 | project_dir = os.path.split(project_dir[0]) 11 | sys.path.append(project_dir[0]) 12 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 13 | wkdir = os.getcwd() 14 | 15 | from performance.libs.set_config import set_custom_config 16 | 17 | custom_config = sys.argv 18 | if len(custom_config) == 1: 19 | logging.info("Use default config for monkey test") 20 | set_custom_config(os.path.join(wkdir, 'user_config/default.conf')) 21 | elif len(custom_config) == 2: 22 | logging.info("Use custom config for monkey test") 23 | config_file = os.path.join(wkdir, custom_config[1]) 24 | if os.path.exists(config_file) is True: 25 | set_custom_config(config_file) 26 | else: 27 | logging.info("Can not find .conf file, please re_check. conf file location input is: %s" % config_file) 28 | sys.exit() 29 | else: 30 | logging.info("Only need one conf file, please check command line") 31 | 32 | from performance.config.config import Config 33 | from performance.libs.device_monitor import monitor_device 34 | 35 | config = Config() 36 | 37 | 38 | def run(): 39 | logging.info('start server') 40 | monitor_device() 41 | 42 | if __name__ == '__main__': 43 | try: 44 | pass 45 | run() 46 | except Exception: 47 | traceback.print_exc() 48 | finally: 49 | pass 50 | -------------------------------------------------------------------------------- /performance/monkey/monkey_stop.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python 2 | # coding: utf-8 3 | 4 | import time 5 | import commands 6 | import re 7 | import os 8 | import sys 9 | import platform 10 | import subprocess 11 | import logging 12 | import traceback 13 | 14 | if __name__ == '__main__': 15 | project_dir = os.path.split(sys.path[0]) 16 | project_dir = os.path.split(project_dir[0]) 17 | sys.path.append(project_dir[0]) 18 | os.chdir(project_dir[0]) # 将项目所在文件夹设置为 wkdir (目录下必须有 __init__.py 文件) 19 | 20 | from performance.config.config import Config 21 | from performance.libs.base import get_device_info 22 | 23 | adb = Config.adb 24 | 25 | def stop_monkey_for_mac(device_id, device_model): 26 | for i in xrange(10): 27 | status, output = commands.getstatusoutput(adb + ' -s %s shell ps | grep monkey' % device_id) 28 | if output == "error: device not found": 29 | logging.debug("Please check device") 30 | elif output == "": 31 | logging.info("no monkey running in %s" % device_model) 32 | break 33 | else: 34 | output = re.search('shell [0-9]+', output).group() 35 | pid = re.search('[0-9]+', output).group() 36 | logging.info("kill the monkey process: %s in %s" % (pid, device_model)) 37 | status, output = commands.getstatusoutput("%s -s %s shell kill %s" % (adb, device_id, pid)) 38 | time.sleep(2) 39 | 40 | def stop_monkey_for_win(device_id, device_model): 41 | for i in xrange(10): 42 | output = None 43 | cmd_pid = "%s -s %s shell ps | grep monkey" % (adb, device_id) 44 | try: 45 | output = subprocess.check_output(cmd_pid) 46 | except Exception: 47 | traceback.print_exc() 48 | if output == '': 49 | logging.info("No monkey running in %s" % device_model) 50 | break 51 | else: 52 | output = re.search('shell [0-9]+', output).group() 53 | pid = re.search('[0-9]+', output).group() 54 | logging.info("kill the monkey process: %s in %s" % (pid, device_model)) 55 | output = subprocess.check_output("%s -s %s shell kill %s" % (adb, device_id, pid)) 56 | time.sleep(2) 57 | 58 | def stop_monkey(device_id, device_model): 59 | if platform.system() == 'Darwin': 60 | logging.debug('This system is Mac') 61 | stop_monkey_for_mac(device_id, device_model) 62 | elif platform.system() == 'Windows': 63 | logging.debug('This system is Windows') 64 | stop_monkey_for_win(device_id, device_model) 65 | else: 66 | logging.info('Do not surpport your system') 67 | 68 | if __name__ == '__main__': 69 | device_dict = get_device_info() 70 | for device_model, device_id in device_dict.iteritems(): 71 | stop_monkey(device_id, device_model) 72 | -------------------------------------------------------------------------------- /performance/monkey/monkeylog/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangyunshuai/monkey_android/64d1b747180048d62ba4877c560d3c30c24f088e/performance/monkey/monkeylog/.DS_Store -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Auto Monkey For Android # 2 | 3 | ### 版本 1.1 4 | 5 | ### 功能简介 ### 6 | 1. 完全自动:只需要负责连接设备 7 | 2. 支持多个设备 8 | 3. 支持随时断开设备、插入新设备,每5s定时检测设备自动运行 9 | 4. 崩溃后,发送邮件,邮件内容:执行时长、crash log 10 | 5. 支持Windows、Mac系统 11 | 6. 支持配置文件 12 | 13 | ### 系统及环境、依赖 ### 14 | 1. 测试环境:Mac OS、Windows 10、Python 2.7.10 15 | 2. 配置 **adb** 16 | 17 | ### 配置修改 ### 18 | user_config/default.conf 19 | 20 | ``` 21 | [config] 22 | package_name = com.testerhome.nativeandroid 23 | adb_location = /your_location/android/sdk/platform-tools/adb 24 | 25 | # 设置邮箱服务器 26 | mail_host = smtp.xxxx.com 27 | # 邮箱账号 28 | mail_user = xxxxxx@xxx.com 29 | # 邮箱密码 30 | mail_pass = ****** 31 | 32 | [mail_to_list] 33 | # 设置发送给收件人, 格式如下,等号右侧留空 34 | aaaaaa@163.com = 35 | bbbbbb@163.com = 36 | 37 | [monkey_parameters] 38 | # monkey 相关的参数,需要哪些,直接在下面按格式添加去掉前面的 # 符号即可. 不需要赋值的参数等号后面留空就可以 39 | -v = 40 | --throttle = 300 41 | --pct-trackball = 0 42 | --pct-syskeys = 5 43 | --pct-nav = 0 44 | --pct-anyevent = 0 45 | # --pct-majornav = 0 46 | # --pct-appswitch = 0 47 | # --pct-flip = 0 48 | # --pct-pinchzoom = 0 49 | # --pct-permission = 0 50 | # --pct-touch = 0 51 | # --pct-motion = 0 52 | 53 | # COUNT 参数需要放最后面 54 | 4000000 = 55 | ``` 56 | 57 | ### 运行 ### 58 | 59 | 1. 执行命令 60 | 执行默认配置文件: user_config/default.conf 61 | 62 | ```shell 63 | python /your_location/monkey_android/performance/monkey/monkey_server.py` 64 | ``` 65 | 执行自定义配置文件(monkey_android/user_config 路径下):user_config/custom.conf 66 | 67 | ```shell 68 | python /your_location/monkey_android/performance/monkey/monkey_server.py user_config/custom.conf 69 | ``` 70 | 或者使用配置文件的全路径 71 | ```shell 72 | python /your_location/monkey_android/performance/monkey/monkey_server.py /your_dir/custom.conf 73 | ``` 74 | 2. 连接手机 75 | 76 | ### 关闭monkey ### 77 | 78 | 1. 停掉monkey_server或当前电脑没有正在运行的 monkey_server 79 | 2. 运行monkey_stop 80 | 81 | ```shell 82 | python /your_location/monkey_android/performance/monkey/monkey_stop.py 83 | ``` 84 | 3. 或连接一台没有monkey_server 的电脑,执行重启手机 85 | 86 | ```shell 87 | adb reboot 88 | ``` 89 | 90 | 91 | ### 邮件截图 ### 92 | summary 93 | 94 | 95 | -------------------------------------------------------------------------------- /user_config/default.conf: -------------------------------------------------------------------------------- 1 | [config] 2 | package_name = com.testerhome.nativeandroid 3 | adb_location = /your_location/android/sdk/platform-tools/adb 4 | 5 | # 设置邮箱服务器 6 | mail_host = smtp.xxxx.com 7 | # 邮箱账号 8 | mail_user = xxxxxx@xxx.com 9 | # 邮箱密码 10 | mail_pass = ****** 11 | 12 | [mail_to_list] 13 | # 发送给收件人, 格式如下 14 | xxxxxx@163.com = 15 | 16 | [monkey_parameters] 17 | # monkey 相关的参数,需要哪些,直接在下面按格式添加去掉前面的 # 符号即可. 不需要赋值的参数等号后面留空就可以 18 | -v = 19 | --throttle = 300 20 | --pct-trackball = 0 21 | --pct-syskeys = 5 22 | --pct-nav = 0 23 | --pct-anyevent = 0 24 | # --pct-majornav = 0 25 | # --pct-appswitch = 0 26 | # --pct-flip = 0 27 | # --pct-pinchzoom = 0 28 | # --pct-permission = 0 29 | # --pct-touch = 0 30 | # --pct-motion = 0 31 | 32 | # COUNT 参数需要放最后面 33 | 4000000 = 34 | -------------------------------------------------------------------------------- /version: -------------------------------------------------------------------------------- 1 | 1.1 --------------------------------------------------------------------------------