AutoClick:基于 Robotium 的自動遍歷方案
前言
? 做這個的初衷是發現項目中的崩潰問題(即穩定性)。Monkey達不到全覆蓋,也試過思寒的 AppCrawler ,無奈速度上不太理想。我需要的是更快的反饋結果,于是乎著手自己寫一個方案,也當做是提高編碼能力,或者說對Android有更深入的理解。
解決了什么
? 初期目標是想替代Monkey,眾所周知Monkey的隨機點擊,以及不可控性,并不能做到完整的遍歷。所以當下最主要的功能是 發現崩潰問題 (如兼容性、混淆、代碼問題導致的崩潰),額外可以做的是發現無數據時的空白布局(配合接口工具,啟用快速模式驗證)、發現無網絡時是否顯示無網絡的布局(關閉網絡,啟用快速模式)等等。
使用效果
? 在我們的產品上,啟用爬蟲模式試跑了幾個小時發現了5個崩潰問題。當然發現第一個崩潰時自動遍歷就停止了,它依賴于被測應用,被測應用崩潰,它也會一同退出,這是接下來要解決的問題( 增加重啟機制 )。當崩潰問題不予修復時,繼續遍歷,還是會走到第一個崩潰( 可復現性 ),此時可以把崩潰的Activity加入忽略列表。
崩潰問題:
-
發現的崩潰問題都是正常操作的,非異常操作(舉例:非人類手速的點擊等等)。換句話說就是用戶也會遇到該問題
-
擅長發現異步請求導致的崩潰問題
- 異步請求拿到數據后更新UI,由于UI被銷毀導致的崩潰
- 為什么說是擅長?
- 遍歷邏輯基于Activity,點擊View跳出本Activity后按返回鍵回到遍歷Activity
- 當網絡不穩定時,數據返回延時加長,View銷毀了數據才回來,如果此時代碼沒處理好就會發生崩潰
- 建議遍歷時切換到弱網環境
?
</li> </ul>特性
-
可跨應用
- 補上Robotium不支持跨應用的短板
- 自動遍歷時不會有具體的跨應用操作,唯一出現的地方在Android 6.0以上版本啟動應用時的授權操作(可能存在兼容性問題)
- 跨應用應用在單獨寫用例時
- 跨應用詳情
-
多種模式
- 快速模式:只啟動Activity,快速檢測崩潰問題(如兼容性、混淆、代碼問題導致的崩潰),一般幾分鐘可完成。依賴于Params.json文件,該文件可由錄制模式產生。
- 迭代模式:啟動Activity并點擊每個View。依賴于Params.json文件,該文件可由錄制模式產生。
- 爬蟲模式:通過迭代主頁并記錄新開Activity,迭代完畢后讀取新開Activity,循環往復,直至無新的Activity。
- 錄制模式:需人工操作應用,記錄每個新開的Activity,供快速模式、迭代模式使用。錄制模式可在功能測試階段使用,錄制模式默認休眠1個小時,期間操作應用打開的Activity都將被記錄下來。 </ul> </li>
-
智能輸入
- 根據輸入框支持的輸入類型和最大長度進行輸入
- 支持手機號、郵箱、普通文本等類型 </ul> </li>
-
紅點標記
- 將要被點擊的View會以紅點標記保存為截圖
- 如果發現截圖沒有紅點或者紅點位置明顯錯誤時,不用驚訝,那一定是隱藏的View被點擊了
- 沒有紅點:隱藏的View坐標不在屏幕范圍
- 紅點標記錯誤:點擊到被遮擋的View,通常發生在ViewPager布局 </ul> </li>
-
無懼遮擋
- 被遮擋的View也可以點擊到,因此無需滑動操作。
- 舉例:列表一次性加載10條數據,屏幕只顯示了5條,剩下5條沒有顯示的也可以點擊到。 </ul> </li>
-
完全遍歷
- 應用所有Activity都可以遍歷到,360°無死角。
- 快速模式、迭代模式覆蓋度最高可達100%,通過爬蟲模式 + 錄制模式組合產生的Params.json文件,或單獨錄制模式產生的Params.json文件。
- 爬蟲模式亦可達到很高的覆蓋度,不同應用覆蓋度不一致,依賴Activity關聯度。
- 提高爬蟲模式覆蓋度的方法:采用劃分模塊的方法,比如主頁模塊、個人模塊等等 </ul> </li>
-
一觸即達
- 只需一步就能打開應用內任何Activity
- 舉例:在已經登錄的情況下,想去到登錄頁面,一般可能的做法是在主頁點擊我,去到個人中心,個人中心滑動到最底部,點擊退出登錄,來到登錄頁面。一觸即達只要知道登錄頁面的名稱、啟動參數就能直接打開登錄頁面。 </ul> </li>
-
可復現性
- 在數據相對不變的情況下,遍歷Activity中View的順序是一致的,因此具備一定的復現可能性,可理解為Monkey中的種子 </ul> </li>
-
多重跟蹤
- 多重跟蹤能在出現崩潰的情況下,更好的定位、復現、分析問題。
- 截圖跟蹤:每個點擊操作都將被記錄,根據截圖順序可知進行了何等操作
- 日志跟蹤:崩潰日志抓取,供研發使用
- 接口跟蹤:配合Fiddler等抓包工具,可知發生崩潰時請求了哪些接口,從而更好的定位問題
- 元素跟蹤:點擊的View信息以操作日志形式記錄在SD card,包含包名、類名、資源ID、屏幕位置、文本等等信息 </ul> </li>
-
支持Hybrid
- 除了支持Native遍歷,亦支持Hybrid </ul>
-
每次點擊后都會判斷是否離開遍歷Activity(未離開則進入下一個點擊事件)
-
如果跳轉到本應用其他Activity(則按下返回鍵返回,返回后回不到遍歷Activity則重啟該Activity并重新遍歷剩余View)
-
如果跳轉到其他應用去了(如相機)則直接重啟該Activity并重新遍歷剩余View
-
如果跳轉到登錄頁面則登錄后繼續操作(可能存在遍歷時點擊到退出登錄按鈕)
?
?
</li> </ul>技術細節(局部)
關于跳轉的處理
關于直接啟動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;</code></pre>
示例:
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(); }
}</code></pre>
AndroidManifest.xml配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="
<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></code></pre>
怎么運行
相關配置都到位了只要運行 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 查看授權界面信息。
來自:https://testerhome.com/topics/7413