您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
基于 Robotium 的自动遍历方案
 
来源:简书 发布于: 2017-4-17
  2162  次浏览      21
 

前言

做这个的初衷是发现项目中的崩溃问题(即稳定性)。Monkey达不到全覆盖,也试过思寒的AppCrawler,无奈速度上不太理想。我需要的是更快的反馈结果,于是乎着手自己写一个方案,也当做是提高编码能力,或者说对Android有更深入的理解。

解决了什么

初期目标是想替代Monkey,众所周知Monkey的随机点击,以及不可控性,并不能做到完整的遍历。所以当下最主要的功能是发现崩溃问题 (如兼容性、混淆、代码问题导致的崩溃),额外可以做的是发现无数据时的空白布局(配合接口工具,启用快速模式验证)、发现无网络时是否显示无网络的布局(关闭网络,启用快速模式)等等。

使用效果

在我们的产品上,启用爬虫模式试跑了几个小时发现了5个崩溃问题。当然发现第一个崩溃时自动遍历就停止了,它依赖于被测应用,被测应用崩溃,它也会一同退出,这是接下来要解决的问题(增加重启机制 )。当崩溃问题不予修复时,继续遍历,还是会走到第一个崩溃(可复现性 ),此时可以把崩溃的Activity加入忽略列表。

崩溃问题:

发现的崩溃问题都是正常操作的,非异常操作(举例:非人类手速的点击等等)。换句话说就是用户也会遇到该问题

擅长发现异步请求导致的崩溃问题

异步请求拿到数据后更新UI,由于UI被销毁导致的崩溃

为什么说是擅长?

遍历逻辑基于Activity,点击View跳出本Activity后按返回键回到遍历Activity

当网络不稳定时,数据返回延时加长,View销毁了数据才回来,如果此时代码没处理好就会发生崩溃

建议遍历时切换到弱网环境

特性

可跨应用

补上Robotium不支持跨应用的短板

自动遍历时不会有具体的跨应用操作,唯一出现的地方在Android 6.0以上版本启动应用时的授权操作(可能存在兼容性问题)

跨应用应用在单独写用例时

跨应用详情

多种模式

快速模式:只启动Activity,快速检测崩溃问题(如兼容性、混淆、代码问题导致的崩溃),一般几分钟可完成。依赖于Params.json文件,该文件可由录制模式产生。

迭代模式:启动Activity并点击每个View。依赖于Params.json文件,该文件可由录制模式产生。

爬虫模式:通过迭代主页并记录新开Activity,迭代完毕后读取新开Activity,循环往复,直至无新的Activity。

录制模式:需人工操作应用,记录每个新开的Activity,供快速模式、迭代模式使用。录制模式可在功能测试阶段使用,录制模式默认休眠1个小时,期间操作应用打开的Activity都将被记录下来。

智能输入

根据输入框支持的输入类型和最大长度进行输入

支持手机号、邮箱、普通文本等类型

红点标记

将要被点击的View会以红点标记保存为截图

如果发现截图没有红点或者红点位置明显错误时,不用惊讶,那一定是隐藏的View被点击了

没有红点:隐藏的View坐标不在屏幕范围

红点标记错误:点击到被遮挡的View,通常发生在ViewPager布局

无惧遮挡

被遮挡的View也可以点击到,因此无需滑动操作。

举例:列表一次性加载10条数据,屏幕只显示了5条,剩下5条没有显示的也可以点击到。

完全遍历

应用所有Activity都可以遍历到,360°无死角。

快速模式、迭代模式覆盖度最高可达100%,通过爬虫模式 + 录制模式组合产生的Params.json文件,或单独录制模式产生的Params.json文件。

爬虫模式亦可达到很高的覆盖度,不同应用覆盖度不一致,依赖Activity关联度。

提高爬虫模式覆盖度的方法:采用划分模块的方法,比如主页模块、个人模块等等

一触即达

只需一步就能打开应用内任何Activity

举例:在已经登录的情况下,想去到登录页面,一般可能的做法是在主页点击我,去到个人中心,个人中心滑动到最底部,点击退出登录,来到登录页面。一触即达只要知道登录页面的名称、启动参数就能直接打开登录页面。

可复现性

在数据相对不变的情况下,遍历Activity中View的顺序是一致的,因此具备一定的复现可能性,可理解为Monkey中的种子

多重跟踪

多重跟踪能在出现崩溃的情况下,更好的定位、复现、分析问题。

截图跟踪:每个点击操作都将被记录,根据截图顺序可知进行了何等操作

日志跟踪:崩溃日志抓取,供研发使用

接口跟踪:配合Fiddler等抓包工具,可知发生崩溃时请求了哪些接口,从而更好的定位问题

元素跟踪:点击的View信息以操作日志形式记录在SD card,包含包名、类名、资源ID、屏幕位置、文本等等信息

支持Hybrid

除了支持Native遍历,亦支持Hybrid

技术细节(局部)

关于跳转的处理

每次点击后都会判断是否离开遍历Activity(未离开则进入下一个点击事件)

如果跳转到本应用其他Activity(则按下返回键返回,返回后回不到遍历Activity则重启该Activity并重新遍历剩余View)

如果跳转到其他应用去了(如相机)则直接重启该Activity并重新遍历剩余View

如果跳转到登录页面则登录后继续操作(可能存在遍历时点击到退出登录按钮)

关于直接启动Activity的处理

通过监听Activity的启动,拿到Activity实例并获取传入参数,看下流程图可能好理解:

配置说明

参数描述:

// Activity截图开关,默认为true。
启动Activity首先会截取一张图保存在sdcard/AutoClick/Screenshots/Activities文件夹
public boolean activityScreenShots = true;
// Activity迭代截图开关,默认为true。
每次点击View会截取一张图保存在sdcard/AutoClick/Screenshots/对应Activity文件夹
public boolean iterationScreenShots = true;
/**
* 迭代模式
快速模式:只启动Activity,快速检测崩溃问题
(如兼容性、混淆、代码问题导致的崩溃),一般几分钟可完成。
依赖于Params.json文件,该文件可由录制模式产生。
迭代模式:启动Activity并点击每个View。依赖于Params.json文件,该文件可由录制模式产生。
爬虫模式:通过迭代主页并记录新开Activity,迭代完毕后读取新开Activity,循环往复,直至无新的Activity。
录制模式:需人工操作应用,记录每个新开的Activity,供快速模式、迭代模式使用。
录制模式可在功能测试阶段使用,录制模式默认休眠1个小时,期间操作应用打开的Activity都将被记录下来。
*/
public Mode mode;
// 被测应用主页,必填项
public String homeActivity;
// 被测应用登录页,必填项
public String loginActivity;
// 被测应用登录账户,必填项
public String loginAccount;
// 被测应用登录密码,必填项
public String loginPassword;
// 被测应用登录页面登录按钮资源ID,必填项
public String loginId;
// 被测应用包名,必填项
public String PACKAGE;
// 忽略的Activities数组,此数组内的Activity不会遍历
public String[] ignoreActivities;
// 忽略的Views数组,此数组内的View不会遍历,需填写完整的资源ID,如com.xx:id/iv_fpc_back
public String[] ignoreViews;
// Activities截图保留开关,默认为true,
如果为false,Activity遍历完成后,截图将会被清理,Activity发生崩溃时,截图不会被清理。
public boolean keepActivitiesScreenShots = true;

示例:

package application.iteration;

import android.test.ActivityInstrumentationTestCase2;

import com.robotium.solo.Solo;

import org.junit.After;
import org.junit.Before;


@SuppressWarnings({"rawtypes", "deprecation"})
public class Iteration extends ActivityInstrumentationTestCase2 {

/**
* 被测应用包名
*/
private static final String PACKAGE = "被测应用包名";

/**
* 被测应用Activity入口
*/
private static final String LAUNCHER_ACTIVITY = "被测应用Activity入口";

private static Class<?> launcherActivityClass;

static {
try {
launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}

@SuppressWarnings("unchecked")
public Iteration() {
super(PACKAGE, launcherActivityClass);
}

private Solo solo;

@Before
public void setUp() throws Exception {
Solo.Config config = new Solo.Config();
// 遍历模式
config.mode = Solo.Config.Mode.REPTILE;
config.homeActivity = "被测应用主页Activity";
config.loginActivity = "被测应用登录Activity";
config.loginAccount = "登录帐号";
config.loginPassword = "登录密码";
config.loginId = "登录按钮ID";
// 被测应用包名
config.PACKAGE = PACKAGE;
config.ignoreActivities = new String[]{"忽略的Activity,此数组中的Activity将不会被遍历"};
config.ignoreViews = new String[]{"忽略的View,此数组中的View将不会被点击,需填入完整的资源ID"};

solo = new Solo(getInstrumentation(), config, getActivity());
super.setUp();
}

@After
public void tearDown() throws Exception {
solo.finishOpenedActivities();
super.tearDown();
}


/**
* 自动遍历入口
* @throws Exception 抛出异常
*/
public void test_iteration() throws Exception {
solo.startIteration();
}

}

AndroidManifest.xml配置

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="被测应用包名.test"
android:versionCode="1"
android:versionName="1.0">

<uses-permission android:name="android.permission.GET_TASKS" />

<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="24" />

<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="被测应用包名" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
</application>

</manifest>

怎么运行

相关配置都到位了只要运行test_iteration()方法即可。

相关截图

跨应用

智能输入

红点标记

一触即达

FAQ

Q: 跳转到其他应用回不去怎么办?

A:可能存在机型兼容问题,如果遇到该情况可以把该View加入忽略数组。

Q:遍历时出现object not found怎么办?

A:Object文件是记录类似序列化的传入参数,记录在sdcard/AutoClick/Object/目录下,务必保证它的存在。

Q:迭代模式下,一会就退出了,并没有遍历?

A:请检查sdcard/AutoClick/Params.json是否存在,或者该文件没有数据?

Q:自动遍历启动不了是什么情况?

A:请根据错误日志检查是否配置文件缺少必备参数,或者签名不一致?

Q:程序中途终止了?

A:确保数据线是连接状态,遍历需要用到adb

Q:Android 6.0及以上版本时,卡在授权界面?

A:如果第三方厂商更改过底层代码,可能出现兼容性问题(如小米),此时需要在Permission.java类中增加相应的包名及授权资源id,通过uiautomatorviewer查看授权界面信息。

Github

AutoClick

结语

欢迎提供指导性意见,大家一同探讨学习

由于水平有限,文中如有错误,请轻拍

代码已经开源,如果觉得对你有帮助,可以star

文章下方有打赏按钮,你的支持是我最大的动力

   
2162 次浏览       21
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新活动计划
LLM大模型应用与项目构建 12-26[特惠]
QT应用开发 11-21[线上]
C++高级编程 11-27[北京]
业务建模&领域驱动设计 11-15[北京]
用户研究与用户建模 11-21[北京]
SysML和EA进行系统设计建模 11-28[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...