Monkey全自动化测试详解【二】
在上一篇Monkey全自动化测试详解【一】中,主要讲解了Monkey的一些基本原理和操作,这篇将主要讲解如何使用Python进行封装,自动化执行Monkey命令和收集logcat日志。
一般我们要执行Monkey测试时都是在终端cmd命令下,编辑Monkey脚本,再enter执行命令,常规的命令基本如下:
adb shell monkey -p com.pingan.mc.offical.distribution --throttle 200 -s 600 --ignore-crashes --ignore-timeouts --ignore-security-exceptions --ignore-native-crashes --monitor-native-crashes -v -v -v 800000 >D:/monkey.txt
在这里,需要指出的是D:/monkey.txt文件只是保存了monkey操作时的各种模拟事件的日志,而并非Android APP异常日志,也就是说当我们执行完命令后,从monkey.txt文件中我们是获取不到具体的异常信息,Android开发也不能根据该文件去处理异常问题,这时我们需要引进一个获取日志命令:
adb logcat >c:\test.log
该导出的日志是包含Android系统和应用的所有日志情况(logcat日志是Android系统自带的源生日志,能够精确的定位分析异常信息,具体logcat日志分析可以百度一下,非常全面,这里我就不细说了),然后再从该日志中去查找我们执行的APP Monkey测试是否存在异常情况,从而获取异常日志信息,交给开发处理,这样才是完整的一次Monkey测试。
Monkey压测,我们所需要重点关注的就是monkey测试执行过程中的APP异常情况。从以上的步骤中,可以看出,常规模式下,我们需要每次手动开启终端cmd,然后再执行Monkey命令,命令结束后,我们还得要手工进行adb logcat日志信息获取,过滤日志,整个过程不仅繁琐,而且操作也不是很方便,不够自动化。
接下来,我们用Python来封装,Python是一个非常强大的脚本语言,你能想到的或者你想不到的,它都能实现。在这里,Python代码中主要使用了三个方法:获取logcat方法、执行monkey脚本方法、获取对应APP进程id的方法,最后再使用多进程的技术同时调用该三个方法。话不多说,直接看代码:
# 获取logcat方法:
def run_log(self, mq):
#subprocess.os.popen("adb logcat -c && adb logcat >D:\\monkey.log") #获取日志,可修改成自己需要保存的路径
filename='D:\\monkey.log'
logcat_file=open(filename, 'w')
#清除log缓存
tlog=subprocess.Popen(args='adb logcat -c',stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(3)
tlog.terminate()
logcmd='adb logcat'
plog=subprocess.Popen(args=logcmd, stdout=logcat_file, stderr=subprocess.PIPE) #更改取日志实现方式,在Monkey结束后停止日志写入
#等待monkey命令结束
while mq and mq.empty() :
time.sleep(3)
plog.terminate()
print('Androind Log Process Over.')
# 执行monkey脚本方法
def run_monkey(self, mq):
subprocess.os.popen("adb shell monkey -p com.foton.loantoc.truck -s 11 --throttle 200 --ignore-crashes --ignore-timeouts --ignore-security-exceptions -v -v -v 100") #执行monkey脚本,修改需要测试的APP包名
# 往mq中推送结束标志
mq.put('MONKEY_END')
print('Monkey Game Over.')
# 获取APP进程id的方法
def run_pro_id(self, mq):
timestr=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
path=u'D:\\'+time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))+'.txt' #保存获取到的进程ip的绝对路径,可修改成自己需要保存的路径
pro_id_file=codecs.open(path,'a+')
pro_id_file.write('StartTime:'+timestr+' \n')
pro_id_file.write('monkey APP PID:'+' \n')
pro_id_text = ''
# 通过mq监听Monkey Over
while mq and mq.empty() :
pids_to_save = ''
result=subprocess.os.popen("adb shell \"ps | grep com.foton.loantoc.truck\"") #获取对应包名的进程ip,修改需要测试的APP包名
for line in result.readlines():
pid=line.split()[1]
#print(pid)
if pid not in pro_id_text:
pids_to_save = pids_to_save + pid + '\n'
if pids_to_save:
# 保存全量pid,无需读取文件
pro_id_text = pro_id_text + pids_to_save
# 增量追加写入文件
pro_id_file.write(pids_to_save)
# N秒获取一次
time.sleep(3)
timestr2=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
pro_id_file.write(u'EndTime:' + timestr2 +' \n')
pro_id_file.flush()
pro_id_file.close()
print('Get Monkey PID Over.')
最后,使用多进程的技术同时调用该三个方法:
mq = multiprocessing.Queue()
#使用多进程实现同时调用三个方法
p1 = multiprocessing.Process(target=controller.run_log, args=(mq,))
p2 = multiprocessing.Process(target=controller.run_monkey, args=(mq,))
p3 = multiprocessing.Process(target=controller.run_pro_id, args=(mq,))
p1.start()
p2.start()
p3.start()
p2.join()
p3.join()
# p2 & p3 都已经结束,此时结束p1
p1.join()
print('Monkey Test Finished')
到此,将以上代码整合在一起,完整的Monkey自动化测试方案就实现了。