Android自動化追本溯源系列(1):獲取頁面元素
本系列旨在闡述Android自動化的原理,讓大家明白如何在Android平臺上做自動化,甚至開發出自己的自動化工具來。
什么是Android自動化?
相信對于測試同 學,這個問題就很簡單了。自動化的目的就是做好回歸測試,以達到版本控制,并節省人力。而Android自動化就是在Android平臺上做測試自動化, 相信隨著Android開發的日趨盛行,其測試自動化的需求也會逐漸增強,知其然,固然是好,但如能知其所以然,必將錦上添花。
目前我所知道的做Android自動化的工具有:
● Ranorex 支持錄制回放功能,但是不太好用,需要在開發代碼中注入一段測試代碼,并且它是收費的。
● Robotium 開源的黑盒測試框架,使用時需要引入一個JAR包,需要測試人員有一定的編碼功底,才能編寫Test Case。
● Monkeyrunner Google隨SDK發布的測試工具,功能簡單,不是很好用。
因為是想研究自動化原理,所以這里主要參考Robotium以及Android源碼。
如何識別頁面元素?
做過自動化的同學應該都知道,我們在寫涉及UI的自動化case時,其基本思路就是找到某元素—>執行操作,這里的操作要么是動作,要么是是驗證。仔細想想,其實道理就是這樣。所以說如果我們想開發自己的自動化測試工具時,首要解決的問題就是,如何在測試時,找到頁面的元素。
而在Android中,思路也是一樣。
如何大家研究過Android的窗口機制的話,應該看到過這樣的說法,真正實現WindowManager窗口機制的是 WindowManagerImpl類,它會把DecorView添加到mViews數組,創建對應的ViewRoot,而DecorView是何物呢? 參考我上篇博客:http://www.cnblogs.com/jinsdu/archive/2013/01/03/2840565.html 知道,實際上DecorView是頁面最頂層的View,而如果能夠獲取到它,我們就可以將其轉換成ViewGroup,然后遍歷其所有子節點從而得到所 有的頁面元素了。而運用java的反射機制,正好可以在運行時,獲取類的屬性和方法:
于是在運行時,獲得WindowManagerImpl類:
private static Class<?> windowManager; static{ try { String windowManagerClassName = "android.view.WindowManagerImpl"; windowManager = Class.forName(windowManagerClassName); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (SecurityException e) { e.printStackTrace(); } } |
然后獲得頁面的DecorView:
private View[] getWindowDecorViews()
{
Field viewsField;
Field instanceField;
try {
viewsField = windowManager.getDeclaredField("mViews");
instanceField = windowManager.getDeclaredField("sWindowManager");
viewsField.setAccessible(true);
instanceField.setAccessible(true);
Object instance = instanceField.get(null);
return (View[]) viewsField.get(instance);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<View> getAllViews() { if (views != null && views.length > 0) { private void getAllChildren(ArrayList<View> allViews, ViewGroup viewGroup) { |
而獲得了頁面的元素,就基本上完成了我們UI Automation兩步走的第一步 —> 找到頁面元素。試想一下,如果我們的Android自動化框架有上面類似的功能,那么我們的自動化框架就能在運行時獲得頁面的所有元素,而我們在寫 case時,也許只要傳給自動化框架一個控件ID,我們就可以獲得這個元素了。有了這個元素我們就可以向我們的第二步邁進了—>在控件上執行操作, 或者取其屬性進行Expected驗證。當然我會在接下來的文章中,一一闡述這些內容。
總結
研究Android自動化原理,要涉及到很多知識,尤其對Android的窗口機制要更加明確,像頁面是如何加載,如何通信,都不是一言半語可 以說清的,我也是正在研究中。對于WindowManagerImpl類的源碼,有興趣的同學,可以研究下:http://grepcode.com /file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/WindowManagerImpl.java#WindowManagerImpl
最后,欲知后事如何,且聽下回分解。
posted on 2013-05-17 10:20 順其自然EVO 閱讀(409) 評論(1) 編輯 收藏 所屬分類: android