测试基础 [分享] 自动化测试与持续集成方案--Android crash 收集

snake · 2015年05月08日 · 最后由 测试小书童 回复于 2016年09月03日 · 5132 次阅读
本帖已被设为精华帖!

之前看到有人在论坛里面问 monkey 的执行,我决定不按照前言中的顺序写了,大家可以各取所需。本篇文章与 Monkey 有关,但又不局限于此。我曾经尝试用 Monkey 来做 crash 的收集。

  1. Monkey 的执行
  2. Log 的分析
  3. Crash 的采集
  4. 思考和讨论

Monkey 的执行


当我刚开始接触移动互联网的时候,到处找关于 Monkey 的文档看,每篇文章都说 Monkey 很简单,就一条命令,然后就是对各种参数的说明。
后面等我实践的时候,发现用好 Monkey 不是件容易的事情。如果仅仅是执行这条命令,当然很容易。一般情况下,跑 Monkey 的同时,获取其 Logcat。对 Logcat 的日志进行分析能发现很多问题。
请看我的实现:

#encoding:utf-8
import os
import time
import re

###############################################################
#########                  Monkey测试                  #########
#########                作者:Anderson 糖果            #########
#########                版本  V1.0.1                  #########
#########                时间:2015.04.25               #########
################################################################

packageName="com.XXXX.app"
logdir=r"d:\jenkins"
remote_path=r"\\10.21.101.100\build\android"

os.system('adb shell cat /system/build.prop >D:\jenkins\phone.text')

f = r"D:\jenkins\phone.text" 

def getcmd(cmd):
    f = open(cmd,"r") 
    lines = f.readlines()
    for line in lines:

        line=line.split('=')
        if (line[0]=='ro.build.version.release'):
            version = line[1]
        if (line[0]=='ro.product.model'):
            model = line[1]
        if (line[0]=='ro.product.brand'):
            brand = line[1]
    return version,model,brand


version,model,brand=getcmd(f)

print version,model,brand
os.remove(f)

#print "使用Logcat清空Phone中log"
os.popen("adb logcat -c")

#print"暂停2秒..."
print "wait"
time.sleep(2)

now1 = time.strftime('%Y-%m-%d-%H_%M_%S', time.localtime(time.time()))

#print"开始执行Monkey命令"
monkeylogname=logdir+"\\"+now1+"monkey.log"
print monkeylogname
cmd="adb shell monkey -p com.XXXX -s 500 --ignore-timeouts --monitor-native-crashes -v -v 10000 >>%s" %(monkeylogname)
os.popen(cmd)   

#print"手机截屏"
os.popen("adb shell screencap -p /sdcard/monkey_run.png")

#print"拷贝截屏图片至电脑"
cmd1="adb pull /sdcard/monkey_run.png %s" %(logdir)
os.popen(cmd1)
print "gai ming"
oldname=logdir+"\\"+r"monkey_run.png"
if (os.path.exists(oldname)):
    print "file is exist"
else:
    print "file isn't exist"
newname=logdir+"\\"+now1+r"monkey.png"
os.rename(oldname, newname)

#print"使用Logcat导出日志"

logcatname=logdir+"\\"+now1+r"logcat.log"
cmd2="adb logcat -d >%s" %(logcatname)
os.popen(cmd2)

#print"导出traces文件"

tracesname=logdir+"\\"+now1+r"traces.log"
cmd3="adb shell cat /data/anr/traces.txt>%s" %(tracesname)
os.popen(cmd3)

Log 的分析


当时在网上找文档时,都是说在 Monkey 的 log 里面找 “FC”,“ANR”。我另劈蹊径,对 Logcat 日志进行解析。

######################
#获取error
######################

NullPointer="java.lang.NullPointerException"
IllegalState="java.lang.IllegalStateException"
IllegalArgument="java.lang.IllegalArgumentException"
ArrayIndexOutOfBounds="java.lang.ArrayIndexOutOfBoundsException"
RuntimeException="java.lang.RuntimeException"
SecurityException="java.lang.SecurityException"

def geterror():
    f = open(logcatname,"r") 
    lines = f.readlines()
    errfile="%s\error.log" %(remote_path)
    if (os.path.exists(errfile)):
        os.remove(errfile)
    fr = open(errfile,"a")
    fr.write(version)
    fr.write("\n")
    fr.write(model)
    fr.write("\n")
    fr.write(brand)
    fr.write("\n")
    fr.write(now1)
    fr.write("\n")

    count=0
    for line in lines:
    if ( re.findall(NullPointer,line) or re.findall(IllegalState,line) or re.findall(IllegalArgument,line) or re.findall(ArrayIndexOutOfBounds,line) or re.findall(RuntimeException,line) or re.findall(SecurityException,line) ):
            a=lines.index(line)
            count +=1
            for var in range(a,a+22):
                print lines[var]
                fr.write(lines[var])
            fr.write("\n")
    f.close()
    fr.close()
    return count


number=geterror()
print number

看到的结果是这样子的:

所有的 crash 都在这个 log 里面展现,一目了然,而且放到了共享目录,开发可以直接访问。其实这里面还统计了出现闪退的次数,为了统计次数,没有去重。(这个脚本还是写得比较粗糙,但是能达到要求了,有兴趣的可以在上面继续优化。)

Crash 的采集


这种方式是能采集到一些闪退,但这远远不够。因为客户那边出现闪退,你是没有现场的。有没有一种方法来监控这些闪退。不管是测试这边还是客户那边,只要有 crash,就会向服务器发请求,将 crash 的具体信息记录在数据库里面。
例如:

后面有跟这个系统的作者有交流,他是重写了线程监控 UncaughtExceptionHandler。他说可以把接口开放给我,我目前还没开始研究。等有了结果,再来分享。

思考和讨论


  1. IOS 上的 crash 如何监控?
  2. 跑 Monkey 时,如何屏幕解锁?有登录咋办? 在登录以后跑,它退出了咋办?
  3. 跑 Monkey 时,怎么避免它将 wifi 或网络关掉?
  4. 开发如何面对这些你捕获的 crash log? (我们的开发有一大堆理由说看不懂,解不了)
  5. 有没有更好的 crash 捕获机制?你们是如何做的?

PS: 最近想挪窝,base 上海,求收留。可以联系恒温和在群里找糖果

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 28 条回复 时间 点赞

现在精神不济,写得自己都不知道在说什么,将就着看吧。

#1 楼 @snake 挪窝的事情,不要反复说啊。。。

提个建议,为了更好的阅读,英文单词前后加空格。其他人也注意。关于 monkey, 这个还远远不够。跑 monkey,需要监控太多数据了。

snake #27 · 2015年05月08日 Author

真早。

哈哈。好思考~呆喔回上海来回帖。。。赶火车去了~赞文章~

IOS 上的 crash 如何监控?
跑 Monkey 时,如何屏幕解锁?有登录咋办? 在登录以后跑,它退出了咋办?
跑 Monkey 时,怎么避免它将 wifi 或网络关掉?
开发如何面对这些你捕获的 crash log? (我们的开发有一大堆理由说看不懂,解不了)
有没有更好的 crash 捕获机制?你们是如何做的?

  1. ios 的 crash, 论坛里有文章了。
  2. 跑 Monkey 时,如何屏幕解锁?有登录咋办? 在登录以后跑,它退出了咋办? —— monkey 做不了逻辑的东西,这个和 monkey 违背。
  3. 跑 Monkey 时,怎么避免它将 wifi 或网络关掉? 所以我们用 串口 跑 monkey 或者把 com.android.settings 加入黑名单
  4. 开发如何面对这些你捕获的 crash log? (我们的开发有一大堆理由说看不懂,解不了) —— 太弱,无解
  5. 有,裁剪自己的 log 系统。然后使用 elk 来做日志分析。

#7 楼 @lihuazhang
串口是什么?
解锁和 appium 一样做个 unlock.apk

#8 楼 @sanlengjingvv 串口,rx tx gnd

@snake 在你该系列第一篇文章,把后面的文章的链接全部更新进去,做成一个合集

最近在做 iOS 的 Monkey 目前已实现真机 monkey 轨迹记录 + 截图 +iPhone 系统日志收集 +crash 日志收集,我是参考的 github 上的 CrashMonkey 和 ui-auto-monkey 自己改造了一些,现在除了那个 app 拉后台怎样重新拉起的问题其它都解决,等完整方案出来会开帖子。

#11 楼 @vigossjjj 等你的帖子等了好久好久了。。

#11 楼 @vigossjjj
期待你的 ios monkey 分析系统啊

snake #15 · 2015年05月11日 Author

@vigossjjj 不错,做了我想做而没做到的事情,大大的赞。

楼主,请问一下代码中的:
for var in range(a,a+22):
这个 22 是怎么来的?

snake #17 · 2015年05月11日 Author

@shixue33 : 哦,是剪烛妹子啊。 这个 22 是表示从找到某个出错的信息开始,打印 log22 行,这个数据你可以根据自己的需要改。基本上 22 行能把所有的出错有关的 log 展现出来了。

#16 楼 @shixue33 为何叫剪烛妹子?

#18 楼 @weamylady =。= 因为叫剪烛啊,然后是妹子啊

#20 楼 @shixue33 (o)/~名字不错哦!我还以为你叫史雪之类的~ ~

有什么办法在 APP ,crash 时自动截屏

snake #23 · 2015年05月25日 Author

@idoit007 一般 crash 时 截屏无助于问题的定位和解决,抓 log 比较靠谱一点。

如果是 UI 自动化测试跑脚本期间遇到的 crash 楼主有什么好点的处理方案?

snake #25 · 2015年05月29日 Author

@jennyhui 这个需要开发帮忙或者开发配合, 在 apk 中加代码来监听 UncaughtExceptionHandler ,将闪退发到服务器或者邮件发出来,这样就不论你啥时候有闪退,都能抓到。本来想做一套这个工具的,结果现在论坛那个入住的企业早已经做出来。

@snake 请问这个是什么语言的脚本啊?python perl?

@Snake,还在考虑机会么?杭州的机会考不考虑?

赞。。。。

测试小书童 [该话题已被删除] 中提及了此贴 09月03日 11:26
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册