Robotium 基于 Robotium 的自动遍历方案——开源

Heyniu · 2017年02月13日 · 最后由 王薇 回复于 2018年12月03日 · 最后更新自管理员 思寒_seveniruby · 3275 次阅读
本帖已被设为精华帖!

前排提醒 :文章稍微长了点,文字占比也高,但是读完你会感觉花费的时间是值得的!

前言

​ 做这个的初衷是发现项目中的崩溃问题(即稳定性)。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

技术细节(局部)

关于跳转的处理

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

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

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

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

关于直接启动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
  • 文章下方有打赏按钮,你的支持是我最大的动力

打赏支持

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

非常强,666666666666666666666

很实用!!6666666

黑妞开挂的节奏!

感谢分享

谢谢分享,慢慢细品中~

挂都不是这么开的。。。

不错,速度有多快呢?

—— 来自TesterHome官方 安卓客户端

学习一下

厉害,晚上引入项目试用一下

Heyniu #10 · 2017年02月13日 作者

#1楼 @sycing
#2楼 @qg__gq
#3楼 @xuxu
我来了,赶紧拿去用,别浪费了。

Heyniu #11 · 2017年02月13日 作者

#7楼 @erickyang 正常操作app的速度,大概1.5-2s点击一次,嫌不够快可以把休眠时间设置小一点。
你看上面那张跨应用的gif图就知道有多快的,秒点

#5楼 @lose github给个星啊😆

能不能避免退出页面后很难回到该页面的问题?比如点了退出登录

老司机开车了

Heyniu #15 · 2017年02月13日 作者

#13楼 @heyyuyu 有判断的,如果不小心退出登录了 点击其他view去到了登录页面会执行一次登录操作,或者最保险的把退出登录按钮资源ID加入忽略的View列表。

Heyniu #16 · 2017年02月13日 作者

#14楼 @kasi 老司机

录制intent 然后回放。楼主想法很给力,star下。
1.如果activity通过非intent方式 就没法遍历到了吧?
2.遍历覆盖率取决于录制的操作?

Heyniu #18 · 2017年02月13日 作者

#17楼 @zhangzhao_lenovo 绝大部分都是通过intent启动的,好像那种插件化以代理的形式代理全部生命周期的就不是通过intent,不是很了解哈。
文中有提到activity的关联度,当然录制也是有关系的。
来个全功能测试,然后全部界面就有了吧,嘿嘿

#11楼 @heyniu 目前我基于uiautomator做的自动遍历也是1.5s左右的时间,还以为可以达到monkey的速度。

—— 来自TesterHome官方 安卓客户端

Heyniu #20 · 2017年02月13日 作者

#19楼 @erickyang 可以达到monkey的速度,我手动休眠了1.5s而已,你看一下文中的图,跨应用那个gif图,够不够快

你好,请问一下 ,LAUNCHER_ACTIVITY、homeActivity... 这些是只需要配置成Actvitiy的名称么(如:MainActviity)?执行时发现报错:Caused by: java.lang.ClassNotFoundException:,配置的LAUNCHER_ACTIVITY未找到

Heyniu #22 · 2017年02月13日 作者

#21楼 @Tonyzhangcanon 看被测应用的是什么就是什么了,比如有的是:com.xx.homeactivity 有的是com.xx.MainActviity

#22楼 @heyniu 嗯,我的意思其实是假如是 com.xxx.xxx.act.MainActivity,我是需要写全,还是只需要写"MainActivity",就可以😜 还在尝试中...

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

这个问题可以通过解析AndroidManifest文件中的permission声明,应用安装之后启动之前再使用 adb shell pm grant <package name> android.permission.* 指令解决。

当然,这样并不符合真实用户的使用场景。

Heyniu #25 · 2017年02月13日 作者

#23楼 @Tonyzhangcanon 写全,需要完整的路径

Heyniu #26 · 2017年02月13日 作者

#24楼 @xubin98246 谢谢你提供的参考,应该有人用得上

你们的开发应该在膜拜你吧😂😂😂,黑妞出品,给力

—— 来自TesterHome官方 安卓客户端

how new be....
xue xi zhong...

恒温 将本帖设为了精华贴 02月14日 08:00

不错

加精理由:设计优秀 工具实用强大 介绍详细

在你的github上加上社区的链接吧 帮社区宣传下 今年的第三届中国移动互联网测试大会 有个优秀开源项目颁奖 你这个项目已经进入提名了 好好搞起来

这个对于webview是否友好?另外如果客户端session容易超时怎么办呢

Heyniu #34 · 2017年02月14日 作者

#27楼 @hu_qingen 这倒没有,我请教过他们很多问题,应该感激他们才对

Heyniu #36 · 2017年02月14日 作者

#32楼 @seveniruby 好,谢谢

Heyniu #37 · 2017年02月14日 作者

#33楼 @Lihuazhang webview没有过多的尝试,只是试过百度和自家产品的web页面,session过时问题可以重新执行一次登录操作?或者由客户端本身控制吧

不错的实用工具

这个要装robotium、fiddler么?可以跨平台么?像fiddler不支持mac

Heyniu #40 · 2017年02月14日 作者

#39楼 @Tank007 你装Charles也行啊,配合接口的不是必要的,只是方便查询错误

#40楼 @heyniu robotium 还需要装么?我看有很多solo调用

Heyniu #42 · 2017年02月14日 作者

#41楼 @Tank007 不用,我在源码基础上改的

#42楼 @heyniu 不错,那要重新签名不?用的debug包

Heyniu #44 · 2017年02月14日 作者

#43楼 @Tank007 重签名测试应用 就是robotium应用 签名与被测应用(你公司产品)一致,没有签名就重签名被测应用吧(不推荐)

Error:ProGuard: [AutoClick] java.io.IOException: Can't read /temp/proguard_input.jar
版本不兼容咋个弄- -

#44楼 @heyniu robotium应用 签名与被测应用(你公司产品)一致,如何知道他们是否一致?

Heyniu #47 · 2017年02月14日 作者

#45楼 @nil 有具体的信息吗

Heyniu #48 · 2017年02月14日 作者

#46楼 @Tank007 如果不一致,启动时日志就会有报错输出

#47楼 @heyniu 有的我截图吧,发现评论有显示限制

Heyniu #50 · 2017年02月14日 作者

#49楼 @nil JDK升级1.8吧

#50楼 @heyniu 我们项目主要用的1.7..不能升级 怕兼容出问题 我晚上回去再看一下 GitHub已经加✨

Heyniu #52 · 2017年02月14日 作者

#51楼 @nil 那就autoclick项目改1.7编译 然后报错的地方 自己兼容一下 应该也是ok的

#52楼 @heyniu 嗯 实践一下回复

非常不错,mark

怎么做到无惧遮挡的😂 😂 appium与robotium的差距么?

#37楼 @heyniu 想请教一下,
在Android端6.0以上,在安装过程中,会出现授权问题。
这块是怎么解决的?

谢谢。

Heyniu #57 · 2017年02月14日 作者

#55楼 @dadeshuo 是基于安卓的辅助功能实现的,拿货不是通过坐标点击的,所以不在屏幕范围内的也可以操作,有点黑科技的味道。

Heyniu #58 · 2017年02月14日 作者

#56楼 @junewang 这个通过跨应用解决的,具体看
https://testerhome.com/topics/7273

#57楼 @heyniu 求详细。。自己写appium还要一点一点滑屏,求优雅的方式!

Heyniu #60 · 2017年02月14日 作者

#59楼 @dadeshuo 这个爱莫能助,appium应该不能做到

public void test_iteration() 之前不需要加@Test吗? 否则怎么run起来?

#58楼 @heyniu 好的,谢了。

#58楼 @heyniu 如果多个页面的activity都一样,这种情况下,用快速遍历的化,还能实现吗?

Heyniu #64 · 2017年02月14日 作者

#61楼 @ansonwoo junit4 不用加,我加了 编译器提示我去掉😂

Heyniu #65 · 2017年02月14日 作者

#63楼 @junewang 在爬虫模式中,如果activity遍历过的就不会再遍历了,快速遍历可以实现,不排重的

在Gradle环境中又修改了几个Error之后已经可以运行
遇到的问题
1.首次启动时需要滑动的Guide页似乎没有操作,手动初始化之后启动了loginActivityy
2.REPTILE模式,登录成功后在首页一只没有操作,Log有在打印(D/StrictMode:,好像似乎想先遍历loginActivity中的控件?一直在打印restart activity : loginActivity)

可以提供一些Log中的Tag 和关键字 ,方便确定下在做什么操作,遇到什么问题之类的😜

#64楼 @heyniu 是run as Android Junit Test吧, 但找不到我电脑连着的android devices. 是api level的问题?

Heyniu #68 · 2017年02月14日 作者

#66楼 @Tonyzhangcanon 首页的滑动不会滑,直接跳过 来到登录页面,restart activity 是因为这个activity启动不了,你们的登录页面启动是否需要参数?因为我默认是没用参数启动的。日志过滤用Robotium可以看到所有操作日志

Heyniu #69 · 2017年02月14日 作者

#67楼 @ansonwoo 这个是你环境问题了,是运行Android Junit Test没错

#68楼 @heyniu 嗯,反正我们的UI自动化也是基于Robotium的,直接先执行初始化Case再遍历就好了;
我们的LoginActivity再登录之后再尝试启动会自动销毁的,是启动不了的,所以一直反复的restart activity 。
想要用,可能还要在你的这个基础上再修改一下😃 ,还在研究中...

Heyniu #71 · 2017年02月14日 作者

#70楼 @Tonyzhangcanon 你去除掉每次启动自动登录就好了

Heyniu #72 · 2017年02月14日 作者

#70楼 @Tonyzhangcanon 加我企鹅 335827476,请教你点问题

😂 我想问下,像微信这种下面4个切换页面的,元素只不过是隐藏了么?辅助功能能直接无视这种结构去点击么??

Heyniu #74 · 2017年02月15日 作者

#73楼 @dadeshuo 这个不能,因为页面还没加载出来啊,就是页面没初始化,要加载出来的,隐藏了就可以点

厉害。留着慢慢学习!

(1) bin下面一直会生成AutoClick.apk, 然后安装这个apk,我指定的apk怎么没安装啊?
(2) 我在Project竟然搜不到"Uploading AutoClick-master.apk onto device..." 这句话. 打开方式不对?

Heyniu #77 · 2017年02月15日 作者

#76楼 @ansonwoo 自己装哇,没有关联你的被测应用的,还有看你提示测试app 被测app签名不一致哦

#77楼 @heyniu 不是很明白 "because package *.test does not have a signature matching the target *". 你这不是重新安装, 也不是同一个渠道包升级, 为什么要求签名一致呢?

Heyniu #79 · 2017年02月15日 作者

#78楼 @ansonwoo 任何情况下 测试app 与被测app签名需保持一致

#79楼 @heyniu
一直提示“Error:Android Packager: [AutoClick] Cannot create new key or keystore”
AndroidManifest.xml 里面修改了获取到的包名,没有重新签名,已经懵逼了

Heyniu #81 · 2017年02月17日 作者

#80楼 @Tank007 哥们,不是叫你换签名吗,你红框的是我项目的签名,换成你项目的签名

很好很强大,感觉好东西都是java写的。

传送门是home的地址,赞一个。

我看了下,挺不多,很符合。但我不是很懂,我先赞下,再来琢磨,学习,运用到项目上。感谢。


@heyniu 请问这是什么原因

Heyniu #86 · 2017年02月23日 作者


这个test runner要重新用编译器改成com.heyniu.auto.InstxxxxRunner

😪 小白还不太会用,先收藏,再学习

Heyniu #88 · 2017年02月24日 作者
guard 回复

放着,养肥了再说

@heyniu 改成自己的keystore后,报错如下 ,是需要哪里设置密码吗?
Error:Android Packager: [AutoClick] java.io.IOException: Keystore was tampered with, or password was incorrect

Heyniu #90 · 2017年02月24日 作者
jennyyung 回复

这个你问下你们的研发吧

@heyniu ,有些应用不需要登录的,有跳过的配置?

Heyniu #92 · 2017年02月25日 作者
lsy 回复

直接填空格就好,不能是null or ""

AutoClick 是单独的一个module吗? 配置了LAUNCHER_ACTIVITY是被测app的PackageName+ActivityName 还是提示java.lang.ClassNotFoundException。应该怎么配置?

Heyniu #94 · 2017年02月27日 作者
隐身 回复

应该是编译器设置的test runner与实际的不符

暂时放弃了,以后有机会再细细的读一遍,赞一个!~

Heyniu #96 · 2017年02月28日 作者
magicyang 回复

好多都卡环境上了,这是我没预算到的

一切技术都为解决实际问题服务,我更感兴趣的是关于多重跟踪这块,希望有更多的图文描述,以供借鉴。

我之前就说了哪个测试工具或者框架能解决环境搭建问题,基本就成功了80%

Heyniu #99 · 2017年03月06日 作者
扫地僧 回复

举个栗子

当发生崩溃时

  • sdcard/AutoClick/package/Crash目录下会产生一个Crash日志

  • 假设日志信息如下

  • 一般日志中有提到哪个界面出现崩溃

    • 如果日志被混淆则,对照mapping.txt查找
  • 如果没有提到哪里出现崩溃则在sdcard/AutoClick/package目录下打开Activities.txt查看最后打开的界面是哪个

  • 通过以上步骤能拿到最后的一个遍历的界面,再到sdcard/AutoClick/package/Screenshots目录下查找该界面的文件夹进入,方可看到遍历该界面的步骤截图

排查

  • 如果截图信息不够详细,可以打开sdcard/AutoClick/package/Log目录下最新的log文件,里面记录着以下日志
    • 被测app打印的日志(如果有)
    • 自动遍历操作日志
    • 点击的元素日志
  • 一般根据以上信息足以跟踪Crash来源
  • 接口的配合(如果遍历时有开启代理)
    • Fiddler代理抓取
    • Charles代理抓取
  • 根据Crash发生的时间逐一排查对应的截图、日志、接口信息尝试手动操作复现

进阶

  • 复现Crash后打开对应的源码,尝试修复
    • 一般通过接口、崩溃日志可定位是接口问题,还是客户端问题
  • 客户端问题
    • 如果是比较简单的错误,如空指针、数组越界等,在发生问题行修改即可(一般情况)
    • 如果是复杂问题,则多打断点调试,找出元凶,根除问题(一般是由于其他问题引起此处代码背锅)
    • Fix bug
    • 编译重测
  • 下一步
    • 联系研发修复bug(此时自己的修复不提交,不符流程,只是作为练手)
    • 研发fix后,查看研发的修复跟自己的是否一致
    • 如果一致,那么恭喜你,你可能已经掌握了这一块的逻辑或者是业务
    • 如果不一致,那么可以对比下,以待进一步提高
    • 久而久之,业务逻辑、研发的处理逻辑、套路,你都会更加了如指掌
    • 良性循环,对业务、源码都有更大的把握,也能找到更深层次的问题,从而推进质量的提升
Heyniu #100 · 2017年03月06日 作者
恒温 回复

看来,有时间我要写一个非常详细的文档才行

Heyniu 回复

人工查有点繁琐,能不能把线索串起来更直观的展现给用户呢

Heyniu #102 · 2017年03月06日 作者
扫地僧 回复

原理都说了,怎么串起来还有难度?

Heyniu 回复

我做的那个就串起来了

Heyniu 回复

是的,因为太多人都没多少基础,但是又需要短时间内用你这个工具,比如说我。我看过思寒的AppCrawler,有视频和文档指引,就很容易上手,但那工具略慢....😂

楼主,这玩意怎么用,有demo介绍吗,实在看不懂,但是又想用。。。

弄了好些时间还是跑不起来,测试启动后被测应用界面闪了下后报错:Test run failed: Instrumentation run failed due to 'java.lang.NullPointerException'
logcat的日志是:
E/AndroidRuntime( 7643): java.lang.RuntimeException: Unable to start activity ComponentInfo{PACKAGENAME/PACKAGENAME.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.TaskStackBuilder android.support.v4.app.TaskStackBuilder.addParentStack(android.app.Activity)' on a null object reference
E/AndroidRuntime( 7643): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
E/AndroidRuntime( 7643): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
E/AndroidRuntime( 7643): at android.app.ActivityThread.access$800(ActivityThread.java:144)
E/AndroidRuntime( 7643): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
E/AndroidRuntime( 7643): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 7643): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime( 7643): at android.app.ActivityThread.main(ActivityThread.java:5221)
E/AndroidRuntime( 7643): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime( 7643): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime( 7643): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
E/AndroidRuntime( 7643): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
E/AndroidRuntime( 7643): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.TaskStackBuilder android.support.v4.app.TaskStackBuilder.addParentStack(android.app.Activity)' on a null object reference
E/AndroidRuntime( 7643): at android.support.v7.app.AppCompatActivity.onCreateSupportNavigateUpTaskStack(AppCompatActivity.java:353)
E/AndroidRuntime( 7643): at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:74)
E/AndroidRuntime( 7643): at PACKAGENAME.MainActivity.onCreate(MainActivity.java:64)
E/AndroidRuntime( 7643): at android.app.Activity.performCreate(Activity.java:5933)
E/AndroidRuntime( 7643): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
E/AndroidRuntime( 7643): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
E/AndroidRuntime( 7643): ... 10 more
W/ActivityManager( 562): Error in app PACKAGENAME running instrumentation ComponentInfo{PACKAGENAME.test/com.heyniu.auto.InstrumentationTestRunner}:
W/ActivityManager( 562): java.lang.NullPointerException
W/ActivityManager( 562): java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.TaskStackBuilder android.support.v4.app.TaskStackBuilder.addParentStack(android.app.Activity)' on a null object reference

请问是哪里出问题了?对robotium不熟悉..

Heyniu #107 · 2017年03月17日 作者
jb 回复

demo后续有空先吧,自己先折腾

Heyniu #108 · 2017年03月17日 作者
Samu Chao 回复

V4包没有这个方法,你看下升级下V4包,问下你们技术V4包版本多少的 替换掉我的,我的是23.3.0

下面是我执行前的环境配置,给需要的同学个参考:
1\使用eclipse导入工程:imports as android project;
2\更改project build target为7.1.1;
3\更改jdk complier compliance level为1.7(本地的java -version为1.8);
4\处理些报错提示,主要是添加final;
5\manifest里面替换被测应用包名;
6\Iteration.java文件中,填写LAUNCHER_ACTIVITY和homeActivity,登录相关的因为用不到用" "代替,其他用不到部分清空;
7\因为项目没有登录页面,屏蔽test_00_login的代码;
8\被测项目用的v4版本更新,更新support-v4-23.3.0(删除自带的support-v4后通过android tools 的 add support library更新);
9\安装后使用命令执行测试:adb shell am instrument -w -r -w -e debug false -e class application.iteration.Iteration#test_01_iteration 被测应用包名.test/com.heyniu.auto.InstrumentationTestRunner
使用eclipse直接执行会报Process crashed

@heyniu 拉了代码实验了下,对部分控件可能支持不是很好,例如spinner,不过思路还是不错

Heyniu #112 · 2017年03月28日 作者
jc 回复

😆 正常啦

主要是来学习老司机的思路。

Heyniu 回复

今天想用下你的自动遍历方案,导入工程后,很多文件错误,想问下这是什么原因导致的?首先我认为你的源码应该是没问题的,但却有很多红叉,是因为我缺少什么吗?比如

Heyniu #115 · 2017年03月28日 作者
周小丽 回复

你的JDK 版本换成1.8的来编译就没这些问题

Heyniu 回复

我JDK是1.84的

Heyniu #117 · 2017年03月28日 作者
周小丽 回复

你要把运行时的jdk调成1.8,估计你现在的是1.6 或1.7,问下你开发

Heyniu 回复

你说的应该是我本地测试环境下的JDK吧?这跟开发没关系啊

Heyniu #119 · 2017年03月29日 作者
周小丽 回复

算了,我打开eclipse 告诉你吧

Heyniu #120 · 2017年03月29日 作者
周小丽 回复

Heyniu 回复

按你这设置后还真少了很多红叉,但还有些红叉,如下提示不知怎么处理,麻烦了啊
[2017-03-29 09:56:45 - AutoClick-power] Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead. Please use Android Tools > Fix Project Properties.

Heyniu 回复

我换成1.7 没那个提示了,但红叉文件仍存在

Heyniu #123 · 2017年03月29日 作者
周小丽 回复

你安卓SDK版本没这么高,你把lolipop的都改成21

我现在没有红叉文件了,但提示Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead. Please use Android Tools > Fix Project Properties.,,,请问你说的 “把lolipop的都改成21”,我看了半天没找到位置

Heyniu 回复

好想用起来 看看是什么效果,是不是只需要配置如下2张图即可?配置对不

Heyniu #126 · 2017年03月29日 作者
周小丽 回复

这里不用全路径,直接:bt_xx 其他应该没错

Heyniu 回复

妞,我现在没有红叉文件了,但提示Android requires compiler compliance level 5.0 or 6.0. Found '1.8' instead. Please use Android Tools > Fix Project Properties.,,,请问你说的 “把lolipop的都改成21”,我看了半天没找到位置

Heyniu #128 · 2017年03月29日 作者
周小丽 回复

我觉得这些环境问题你可以找你们开发帮忙的

恒温 [LuckyFrame] V1.0 版本-开源自动化平台 中提及了此贴 03月29日 15:17
130楼 已删除
Heyniu 回复

请问下,签名文件放在哪个目录下啊?运行报错:Test run failed: Permission Denial: starting instrumentation ComponentInfo{com.qshealthcare.com.wtmd.test/com.heyniu.auto.InstrumentationTestRunner} from pid=16063, uid=16063 not allowed because package com.qshealthcare.com.wtmd.test does not have a signature matching the target com.qshealthcare.com.wtmd

Heyniu 回复

嗨 妞,我没找到签名文件放的目录,麻烦帮看下

@heyniu 用szhomebbs.keystore重签名我的应用,需要用户名和密码么?

Anson 回复

问下你最后那个签名的问题是怎么解决的啊?我不知道签名文件放哪

Samu Chao 回复

@samu 8\被测项目用的v4版本更新,更新support-v4-23.3.0(删除自带的support-v4后通过android tools 的 add support library更新);
替换后不影响编译吧?

dadeshuo 回复

授权问题,appium可以解决啊,同时也可以不用滑屏吧 获取android常见控件名称,开启多线程,不停获取可以点击的控件,然后点击就可以了吧

弄了两天了,一直运行不成功,楼主能写个环境搭建的流程吗,毕竟每个人环境不一样,都快放弃 了

Heyniu #138 · 2017年04月17日 作者
邓琳 回复

如果环境问题搞不定的话,那你暂时还是放弃吧

你好,我这边弄下来提示找不到依赖了,是什么更新了吗请问,需要如何解决

junit.framework.AssertionFailedError: Exception in constructor: test_00_login (java.lang.ClassNotFoundException: com.qianxun.comic.apps.WelcomeActivity
环境都配置好了,报这个错,我是android studio上面弄的,请问大神,我这边是上面步骤没弄好吗

Heyniu #142 · 2017年04月18日 作者
深蓝 回复

robotium的包别用官方的,用我项目中的5.6.3

Heyniu 回复

有什么不一样啊,做了什么改动了

Heyniu #144 · 2017年04月19日 作者
bauul 回复

把一些private 改成了public

Heyniu 回复

库是用的你的库

深蓝 回复

打开Run/Debug Configurations,看看是否已android junit启动了?
改成以Android Instrumented tests方式启动就好了
我也是用的android studio

http://stackoverflow.com/questions/2422378/intellij-idea-with-junit-4-7-junit-version-3-8-or-later-expected
The latest Android Studio might have this issue with slightly different case, the test class/method should be fall under Android Tests instead of JUnit in Run/Debug Configurations. See my answer below.

Anson 回复

@ansonwoo 求问这个问题是如何解决的?

@heyniu 想请问一下,对于已经安装在系统里的应用是否可以遍历?无APK。

深蓝 回复

请问这个问题解决了吗,是怎么解决的呢

@heyniu 楼主好,我把你的遍历工程导入到Android Studio上。在Android Studio可以运行,但是想通过断点的方式看看整体的执行流程,却发现不能debug。网上找了好久也没解决,请问需要什么配置么。

错误告警如下:

Error running Iteration:
Cannot debug application from module AutoClick on device lge-nexus_5-055846c6f0df5ffb.
This application does not have the debuggable attribute enabled in its manifest.
If you have manually set it in the manifest, then remove it and let the IDE automatically assign it.
If you are using Gradle, make sure that your current variant is debuggable.

Heyniu #151 · 2017年08月03日 作者
autotester1 回复

不用debug,你打印日志或者看源码就行了

Crazyerick 回复

基于uia的开源么

Heyniu 回复

请问,你这个工程,我可以导入到android studio中么?非常感谢!

Heyyu 回复

楼主,能不能提供一个andorid studio工程啊,现在很少人用eclipse了。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册