有没有人尝试过Android UITesting
框架UIAutomator
?
当我使用类UiScrollabl
“在可滚动对象中查找某些对象时,如果可滚动对象的长度为,则无法找到该对象太长了(需要刷两次才能找到它),比如“设置”应用中的“开发人员选项”。
有没有人有同样的问题?
答案 0 :(得分:8)
我通过覆盖UiScrollable
类修复了它。
public class UiScrollable extends com.android.uiautomator.core.UiScrollable {
public UiScrollable(UiSelector container) {
super(container);
}
@Override
public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException {
if (exists(getSelector().childSelector(selector))) {
return (true);
} else {
System.out.println("It doesn't exist on this page");
// we will need to reset the search from the beginning to start search
scrollToBeginning(getMaxSearchSwipes());
if (exists(getSelector().childSelector(selector))) {
return (true);
}
for (int x = 0; x < getMaxSearchSwipes(); x++) {
System.out.println("I'm going forward a page: " + x);
if(!scrollForward() && x!=0) { // x!=0 is the hack
return false;
}
if(exists(getSelector().childSelector(selector))) {
return true;
}
}
}
return false;
}
}
我已经复制了源代码:UiScrollable.java(可能会在某些时候过时,要小心),只需更改if(!scrollForward() && x!=0)
行。
根据我的观察,如果Google的ui测试页面上的示例代码滚动设置应用的应用屏幕,scrollForwards()
方法在第一次尝试时失败。天知道为什么。
上面简单地说如果它在第一卷上失败,则继续进行。如果它无法在第二个滚动滚动,那么它确实会返回失败。
答案 1 :(得分:4)
要查找视图中需要滚动的任何元素,我使用了下面提到的方法,它似乎工作正常。
public void searchForText(String searchText)
throws UiObjectNotFoundException {
UiScrollable textScroll = null;
UiObject text = null;
if (searchText != null) {
textScroll = new UiScrollable(new UiSelector().scrollable(true));
textScroll.scrollIntoView(new UiSelector().text(searchText));
text = new UiObject(new UiSelector().text(searchText));
text.click();
}
}
答案 2 :(得分:3)
您能否提供更多详情,例如
我提出这些问题的原因是因为UIAutomator存在一些特定于版本的问题。例如,我发现在Android 4.2.2的设备上运行的滚动问题看起来与您提到的类似。我编写了一个解决方法,如果标准的Android方法似乎没有找到我希望可用的元素,我的代码会滚动。
我在这里复制了我的代码的精髓,你会在http://blog.bettersoftwaretesting.com/?p=84找到完整的例子
// The following loop is to workaround a bug in Android 4.2.2 which
// fails to scroll more than once into view.
for (int i = 0; i < maxSearchSwipes; i++) {
try {
appToLaunch = appViews.getChildByText(selector, nameOfAppToLaunch);
if (appToLaunch != null) {
// Create a UiSelector to find the Settings app and simulate
// a user click to launch the app.
appToLaunch.clickAndWaitForNewWindow();
break;
}
} catch (UiObjectNotFoundException e) {
System.out.println("Did not find match for " + e.getLocalizedMessage());
}
for (int j = 0; j < i; j++) {
appViews.scrollForward();
System.out.println("scrolling forward 1 page of apps.");
}
}
注意:我不知道此代码是否能解决您的问题,因为我没有您的应用示例。如果您能够发布测试和相关UI的XML布局,则可以更轻松地诊断问题。
答案 3 :(得分:1)
我通常使用UiDevice
的{{1}}比使用drag()
的方法更幸运。
答案 4 :(得分:1)
我也遇到IDialog
只滚动一次,我试着追踪它。
我发现根本原因可能来自系统。
当您致电getChildByText
时,其流程为:
getChildByText
在getChildByText -> scrollIntoView -> scrollForward -> scrollSwipe
中,系统将运行刷卡命令,等待,而不是在当前屏幕中查找所有scrollSwipe
和过滤器AccessibilityEvent
。此步骤使UiScrollable再次滚动或最后检查它。
但是错误就在这里,系统无法正确返回AccessibilityEvent.TYPE_VIEW_SCROLLED
。
AccessibilityEvent
我认为最好的方法是覆盖代码并定义合适的public boolean scrollSwipe(final int downX, final int downY, final int upX, final int upY,
final int steps) {
Runnable command = new Runnable() {
@Override
public void run() {
swipe(downX, downY, upX, upY, steps);
}
};
// Collect all accessibility events generated during the swipe command and get the
// last event
ArrayList<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>();
runAndWaitForEvents(command,
new EventCollectingPredicate(AccessibilityEvent.TYPE_VIEW_SCROLLED, events),
Configurator.getInstance().getScrollAcknowledgmentTimeout());
//**Root cause**
//Some times the events list size will be 0 ,
//but in fact it can scroll again.
Log.e(LOG_TAG,"events size = " + events.size());
AccessibilityEvent event = getLastMatchingEvent(events,
AccessibilityEvent.TYPE_VIEW_SCROLLED);
if (event == null) {
// end of scroll since no new scroll events received
recycleAccessibilityEvents(events);
return false;
}
...
..
.
}
,如果项目超过此大小,则使测试失败。
MaxSearchSwipes
答案 5 :(得分:0)
scrollableObject.scrollIntoView(btn_1);
try {if(scrollableObject.scrollIntoView(btn_1))
btn_1.click();
}
catch (UiObjectNotFoundException e){
System.out.print("error1: "+e);
}
不确定这是否可以帮到你,但这就是我在我的应用中所做的。第一行是让它滚动直到找到btn_1,然后如果它找到了对象,它就会对它进行点击。