偶尔翻到几个帖子谈到 Android ScrollView 和 ios UIATable 如何获取所有子元素的问题. 正好最近写了个类似的东西, 随意拍砖..
公司目前 UI 的自动化测试框架是基于 appium 搭建的, 各种封装以及分层就不谈了, 最主要的目的是让同一套自动化测试代码能同时运用在 android 和 ios 平台上 (基础是 app 在 Android 和 IOS 上的 UI 功能测试用例一致或极为类似).
思路其实很简单, 基本就以下 2 点.
public mListView(By by) {
super(by,mListView.class);
rootPath = by.getParameter();
//设置子节点路径
if(by.getType().equalsIgnoreCase("ById")){
String id = by.getParameter();
childrenPath = "//*[@resource-id='"+id+"']";
}
//查找节点下元素, 并维护列表
IMegaElement save;
IMegaElement last;
List<IMegaElement> tempChildren = app.findElements(by);
do{
children.addAll(tempChildren);
save = tempChildren.get(tempChildren.size()-1);
save.scrollTo();
tempChildren = app.findElements(by);
last = tempChildren.get(tempChildren.size()-1);
}while(!last.equals(save));
Iterator<IMegaElement> it = children.iterator();
while(it.hasNext()){
names.add(it.next().getAllText());
}
size = children.size();
}
Element 对象表示的是 List 中的一个元素. hashCode() 方法中 index 为该元素在列表中的位置, 这个是在查找元素并创建对象的时候设置的.
protected Element(WebElement webElement, IMegaApp app,By by) {
this(webElement,app,by,-1);
}
protected Element(WebElement webElement, IMegaApp app, By by,int index){
this.webElement = (MobileElement) webElement;
id = ((MobileElement) webElement).getId();
this.app = app;
this.by = by;
this.index = index;
log = new Log(this.getClass().getSimpleName());
}
@Override
public boolean equals(Object object){
if(!(object instanceof IMegaElement))
return false;
Element other = (Element) object;
if(hashCode()!=other.hashCode())
return false;
return true;
}
@Override
public int hashCode(){
if(childrenText.isEmpty())
getAllText();
return (this.by.getType()+this.by.getParameter() + text + childrenText).hashCode();
}
因为随着 ScrollView 的滚动, Android 中页面元素的 Id 会发生变化, 所以如何判断相对的对象比较麻烦, 我们使用的是元素本身及子节点的 text 相同及认为是同一个元素, 缺点就是如果一个容器中有 2 个对象的 text 完全一致就会有点问题, 不过貌似这也对用户也不友好. 以上内容仅是提供一个实现思路, 整体工程代码较多就不贴全了..