使用UI Automator对ListView,RecycleView,GridView进行遍历
背景:
程序写完总要进行测试,android程序也不例外。UI Automator就是这么一款给开发者使用的测试工具。
UI Automator
UI Automator 是一个界面测试框架,适用于整个系统上以及多个已安装应用间的跨应用功能界面测试。
UI Automator 测试框架提供了一组 API,用于构建在用户应用和系统应用上执行交互的界面测试。UI Automator 测试框架非常适合编写黑盒式自动化测试,此类测试的测试代码不依赖于目标应用的内部实现细节。
虽然说是黑盒测试,但是还是需要一定的编程基础才能编写测试代码。
首先需要使用UI Automator 查看器或者android studio的Layout inspector来扫描和分析 Android 设备上当前显示的界面组件。使用工具来检查布局层次结构并查看设备前台显示的界面组件的属性,然后根据这些信息来组织测试代码。
步骤:
在antomaterui中对进行列表ListView,RecycleView,GridView的遍历,并没有什么区别。
antomaterui2只是对antomaterui1进行了优化,多了一些更炫,更简化的使用方法,对列表遍历没有什么区别。
首先找出要遍历的列表的父类是什么,比如如果你使用XRecycleView,那就使用android.support.v7.widget.RecyclerView做遍历容器。
为什么呢?测试发现UiAutomator只能识别anrdoid.jar中的类型,比如ListView,RecycleView,GridView,不能使用自定义类型。
然后定义选择器,获取滚动集合,一行行的遍历即可。下面是我使用的测试例子,把它提取出来。
GridView:
public static void testGridView() {
//查询基于GridView的网格控件
UiSelector uiSelGridView = new UiSelector().className("android.widget.GridView");// 列表选择器
UiSelector uiSelGridItem = new UiSelector().className("android.widget.RelativeLayout");//列表中的行选择器
// 主窗口模块
UiSelector uiSelGridText = new UiSelector().className("android.widget.TextView")
.resourceId(ViewUtils.RESID + "/tvName");// 列表中的子项
UiScrollable listOperate = new UiScrollable(uiSelGridView);//滚动集合对象
try {
int countOperate = listOperate.getChildCount();//行数量
for (int j = 0; j < countOperate; j++) {//遍历所有的Grid Item
UiObject operate = listOperate.getChildByInstance(uiSelGridItem, j);
UiObject textObj = operate.getChild(uiSelGridText);
Globals.printLog("ua2", "operate " + j + " name=" + textObj.getText());
if (textObj.getText().equalsIgnoreCase("查看")) {
ViewUtils.viewClick(operate, 1);// //打开
}
}
} catch (UiObjectNotFoundException e) {// Exception
Globals.printErr(e, "testTalk startVisit");
}
}
ListView
public static void testListView() {
//查询基于ListView的列表控件
Globals.sleep(1000);
UiSelector uiSelList = new UiSelector().className("android.widget.ListView")
.resourceId(ViewUtils.RESID + "/xListView");//用来找到列表
UiSelector uiSelListItem = new UiSelector().className("android.widget.LinearLayout")
.resourceId(ViewUtils.RESID + "/list_item_table_layout");//列表子项的rootview
UiSelector uiSelName = new UiSelector().className("android.widget.TextView")
.resourceId(ViewUtils.RESID + "/list_item_name");//列表子项的字段
UiScrollable listUser = new UiScrollable(uiSelList);//滚动列表
if (!listUser.exists()) {
return;
}
int countItem = 0;
try {
countItem = listUser.getChildCount()-1;
Globals.printLog("ua2", "list items count" + countItem);// 得到列表对象
for (int index = 0; index < countItem; index++) {//{//遍历所有的List Item
UiObject listItems = listUser.getChildByInstance(uiSelListItem, index);// 获取一行
if (listItems.exists()) {// 每一行都可点击
ViewUtils.viewClick(listItems, 1);// //打开
} else {
continue;
}
UiObject myPatient = listItems.getChild(uiSelName);// 从每一行获取某个字段
if (myPatient.exists()) {
//ViewUtils.viewClick(myPatient, 0);// //打开
}
MotionUtils.mouseMoveVertical(800);//TODO 列表向上拖动
//break;//TODO 只循环一次,否则循环现有的所有用户。
}
} catch (UiObjectNotFoundException e) {
e.printStackTrace();
}
}
RecyclerView
public static void testRecyclerView() {
// 查看基于RecyclerView的列表控件 // UiAutomator只能识别anrdoid.jar中的类型
// 如果调用了RecyclerView或Listview的子类,在选取类选择器的时候只能使用这些基类,而不能使用自定义类。并且只能使用基类的方法。
Globals.sleep(1000);
UiSelector uiSelList = new UiSelector().className("android.support.v7.widget.RecyclerView")
.resourceId(ViewUtils.RESID + "/rrv_data");//用来找到列表
UiSelector uiSelListItem = new UiSelector().className("android.widget.LinearLayout");//列表子项的rootview
//UiSelector uiSelListItem = new UiSelector().className("android.widget.LinearLayout")
//.resourceId(ViewUtils.RESID + "/list_item_table_layout");//rootview存在id
UiSelector uiSelConsult = new UiSelector().className("android.widget.TextView")// 子项中的字段
.resourceId(ViewUtils.RESID + "/tv_show_consult");
UiScrollable listUser = new UiScrollable(uiSelList);//滚动列表
if (!listUser.exists()) {
return;
}
int countItem = 0;
try {
countItem = listUser.getChildCount()-1;
Globals.printLog("ua2", "list items count" + countItem);// 得到列表对象
for (int index = 0; index < countItem; index++) {// 最后一个元素是下拉刷新是RelativeLayout
UiObject listItems = listUser.getChildByInstance(uiSelListItem, index);// 获取一行
if (listItems.exists()) {
ViewUtils.viewClick(listItems, 1);//点击每一行
} else {
continue;
}
UiObject consultItem = listItems.getChild(uiSelConsult);//从每一行获取某个字段
if (consultItem.exists()) {
ViewUtils.viewClick(consultItem, 0);// //打开
// String nameUtf8 = myName.getText();// antomaterui需要处理字符集,antomaterui2不需要特别处理了
// Globals.printLog("ua2","alarm item name=%s\n"+ nameUtf8);
//Globals.goback( 1);
// break;//只循环一次,否则循环现有的节点。
} else {
Globals.printLog("ua2", "alarm item not have=list_item_patient \n");
}
}
} catch (UiObjectNotFoundException e) {
e.printStackTrace();
}
//Globals.wait(5000);
// Globals.goback( 3);//视频窗口禁用了后退物理键
}
可以看到它们实际上大同小异:
本文地址:https://blog.csdn.net/lgs790709/article/details/107456545