最近一段时间,真的是忙成狗,不过也却是成长的很快,会陆陆续续将干货分享出来
在实际的自动化测试过程中,由于app的不稳定,经常会出现app奔溃,或者元素找不到的情况,这种情况就会导致测试用例失败或者更有甚者是脚本无法运行下去,这个时候就希望将app重新启动起来。
需要重启app,我们分两个业务场景来分析
- app奔溃,报crash时的app重启
- 找不到定位元素,重启app,重新走测试用例(这种情况要结合自己的业务场景具体问题具体分析,有些定位不到元素的问题本身就是用例的失败)
从技术上分析
存在以下几个疑问:
- crash之后,appium和客户端直接的session 是否会断掉?
- 如果重启app,appium和客户端的是需要重新建立连接创建session吗?
之前的session数据还会保留吗?数据是不是就丢失了?
何以解忧,唯有实践,实践出真知
(只是将核心代码贴出来,主要是讲思路)
- crash的时候,重启app
String cmd2 = "adb shell am start -n com.synative.zepra/com.synative.zepra.features.launch.SplashActivity";
//cmd的方式执行命令
cmdUtils.cmdExecute(cmd2);
//重启之后,给app一点加载的时间
for(int i=1;i<=6;i++){
//休眠时间这样子写,是类似于appium和客户端端之间的心跳请求
//是因为,appium在60s之内没有接收到新的命令,则会断掉session
driver.getContext();
Thread.sleep(5000);
}
//重新执行测试用例
doAction(driver);
结果:运行脚本,发现重启app之后,没有创建新的session,还是保留原来的session连接,并且可以接着执行用例。
这个结果让人皆大欢喜,之前的疑虑都是不存在的问题。
这个问题解决的似乎有点简单呢,一般情况下此处都应该是有一个转折的,果不其然呢?
找不到元素的时候,重启app
找不到元素的时候,也采用了此方法重启app,但是没有重启成功;
Starting: Intent { cmp=com.synative.zepra/.features.launch.SplashActivity }
Warning: Activity not started, its current task has been brought to the front
简单来说,这个activity还在运行,不能再重启一个。解决办法,把这个activity先kill掉,之后再重启就OK了。
为什么
为什么会是这样子的呢?这两种重启有什么不一样吗?
一方有难,八方资源来搜索,终于得出结论:
- app发生crash之后,app的进程就被kill掉了
- 非crash想重启app,此时app的进程是还在运行的
最后的最后
调整代码如下:
//cmd1 先杀进程,cmd2重启app
String cmd1 = "adb shell am force-stop com.synative.zepra";
cmdUtils.cmdExecute(cmd1);
String cmd2 = "adb shell am start -n com.synative.zepra/com.synative.zepra.features.launch.SplashActivity";
cmdUtils.cmdExecute(cmd2);
for(int i=1;i<=6;i++){
driver.getContext();
Thread.sleep(5000);
}
doAction(driver);
这样就可以稳妥妥的重启app啦。
道路崎岖坎坷,还好一路荆棘都可以迈过,很喜欢这个feel,就是这个feel,倍儿爽!