腾讯Android自动化测试实战
上QQ阅读APP看书,第一时间看更新

3.3 Robotium实践运用

3.3.1 控件ID相同时获取控件

实际界面中常常有一些子控件是相同ID甚至没有ID的,但这时候一般其父视图是有ID的。如图3-14所示,每个TAB的控件ID是相同的。

图3-14 拥有相同ID的底部TAB

因为界面中也很可能会出现多个发现、游戏这样的文本,因此也不能采取类似getText (“发现”)这样的方式。这里,我们就可以通过ID获取唯一父控件,再通过过滤方式获取指定的控件。

          //先根据ID获得唯一的布局LinearLayout
          LinearLayout mTabs = (LinearLayout)solo.getView("main_tabs");
          //然后通过过滤方式获取该LinearLayout下的所有文本控件
          ArrayList<TextView> tabs = solo
                        .getCurrentViews(TextView.class, mTabs);

如果子控件的ID都是一样的,而我们仍然希望通过ID来定位控件,那么应该如何获取呢?我们知道不论是Activity类还是View类都是可以通过findViewById(int id)方法直接在控件树中根据ID来查找控件的,因此当我们获得一个父视图后,就可以通过findViewById (int id)方法根据ID来查找相应的子控件,这种方法可以普遍应用在ListView中。

          //先根据ID获得唯一的布局ListView
          ListView mListView = (ListView)solo.getView("example_list_id");
          //先通过mListView.getChildAt(0)获取该ListView的第一个child,然后再通过该
          //child在控件树中使用findViewById根据ID来获取
          TextView firstListTitle = (TextView) mListView.getChildAt(0).findViewById(getId
          ("example_title"));

这里的重点是findViewById(int id)传进去的是int型的ID,而我们通过hierarchyviewer或uiautomatorviewer查看到的ID都是String型的,由前文的原理介绍可知,我们可以将String型的ID转换成int型的ID,如代码清单3-19所示:

代码清单3-19 将String型的ID转换成int型的ID

        public int getId(String id, String packageName){
            Context targetContext = instrumentation.getTargetContext().getApplicationContext();
              int  viewId  =  targetContext.getResources().getIdentifier(id,   "id",
    packageName);
            LogUtils.logD("CopyOfAssistantTabActivityTest", "viewId:" + viewId);
            if(viewId == 0){
                    viewId  =  targetContext.getResources().getIdentifier(id,  "id",
    "android");
            }
 
            return viewId;
        }

因此,当碰到同一层级控件ID相同时,可以先寻找唯一的父布局,再通过父布局寻找子控件。如果子控件结构均相同,那么可以通过index索引来查找;如果子控件结构不一致,则可以通过遍历的方式找到指定的子控件。