我使用以下脚本在Android中使用UiAutomator在计算器中输入“33”。但是,只接受第一个'3',第二个按下完全被忽略。
import com.android.uiautomator.core.*;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;
public class MyFirstUiAutomatorTest extends UiAutomatorTestCase {
UiObject getByDescription(String description) {
return new UiObject(new UiSelector().description(description));
}
UiObject getByText(String description) {
return new UiObject(new UiSelector().text(description));
}
UiObject scrollableGetByText(String text ) throws UiObjectNotFoundException {
UiScrollable uiScrollable = new UiScrollable(new UiSelector().scrollable(true));
uiScrollable.setAsHorizontalList();
return uiScrollable.getChildByText(new UiSelector().className(
android.widget.TextView.class.getName()),
text);
}
public void testStuff() throws UiObjectNotFoundException {
getUiDevice().pressHome();
getByDescription("Apps").clickAndWaitForNewWindow();
getByText("Apps").click();
scrollableGetByText("Calculator").clickAndWaitForNewWindow();
// pressing '+' and '=' effectively clears the previous input
getByText("+").click();
getByText("=").click();
getByText("3").click();
// this second '3' is ignored
getByText("3").click();
}
}
我在第一次点击后尝试添加睡眠2秒,方法是:
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
......但这并没有改变任何事情。
我也试过点击2'3之间的另一个按钮,即:
new UiObject(new UiSelector().text("3")).click();
new UiObject(new UiSelector().className("android.widget.EditText")).click();
new UiObject(new UiSelector().text("3")).click();
......但这也不起作用。
想法?
(注意:在AVD中使用Android 4.1.2;在Ubuntu linux 12.04上运行)
编辑,按照Rami的观察,我尝试了以下操作,为同一描述的第二个请求重用相同的UiObject对象:
HashMap<String,UiObject> objectByText = new HashMap<String,UiObject>();
UiObject getByText(String description) {
if( objectByText.containsKey(description)) {
System.out.println("" + objectByText.get(description) );
return objectByText.get(description);
}
System.out.println("Created new object for [" + description + "]");
UiObject object = new UiObject(new UiSelector().text(description));
objectByText.put(description, object );
System.out.println("" + object );
return object;
}
...但是它没有用,即使它每次都明显重复使用相同的UiObject,因为它只会说“为[3]创建一个新对象”。
然后我尝试了UiDevice.click()'技巧',再次按照Rami的观察创建一个函数'click':
void click(UiObject target ) throws UiObjectNotFoundException {
Rect rect = target.getBounds();
System.out.println("rect: " + rect );
getUiDevice().click(rect.centerX(), rect.centerY());
}
然而,这对我来说也不起作用:只显示第一个'3',第二个被忽略,即使两个点击明显位于同一位置,因为rect:
输出位置相同。如果我手动点击“3”,使用我自己的桌面鼠标,则两个3都显示正常。
我还尝试在点击之间添加两秒Thread.sleep()
,但仍然只为我出现了一个“3”。
答案 0 :(得分:4)
不要只按文字搜索,而是尝试按文字和课程搜索。 这是一个这样做的示例方法。
Uiobject getByTextAndClass(String text, String className) {
return new UiObject(new UiSelector().text(text).className(className));
}
然后,如果您尝试将此方法用于其上带有数字3的计算器按钮:
getByTextAndClass("3", android.widget.Button.class.getName()).click();
您可以使用UiAutomatorViewer工具:{android-sdk} /tools/uiautomator.bat来检查不同UiObjects的类名和其他属性。
这适用于我的4.2.2设备,但我也在下载4.1.2以在那里进行测试。
我在4.1.2 AVD上尝试过,它可以在我的Windows机器上运行。
答案 1 :(得分:2)
我现在发现了一个小问题来解决这个问题。每次运行测试时都要获得边界,这样它就不会以设备为中心,并且会在运行中适应。
UiObject obj1 = new UiObject(new UiSelector().text("4"));
Rect four = obj1.getBounds();
getUiDevice().click(four.centerX(), four.centerY());
答案 2 :(得分:2)
这个问题似乎与UiObject的设置方式有关。据我所知,UiObject的一个实例似乎并没有引用屏幕上的特定对象。它更像是在定义UiObject时UiSelector所指向的实例。这里的关键是每次调用对象时,它都会搜索符合UiSelector要求的新项目。
证据:
UiObject ok = new UiObject(new UiSelector().text("OK"));
ok.click();
// clicks a button with the text ok on the page
// Navigate to some different page with a button with the text ok
ok.click();
// this ok button on a completely different page is still clicked
因此,我认为Rami的解决方法实际上可能采用正确的方法(通过坐标存储对象的位置并单击该位置的中心)。关于Rami的解决方法需要注意的重要事项,保存坐标/矩形一次,然后在需要引用对象时重复使用坐标/矩形。在同一个对象上多次使用obj.getBounds()似乎不起作用。
此外,在UiObject实例化期间已经传递的项目的记录似乎存储在应用程序中。运行两次测试以找到UiObject(例如设置警报页面中的按钮4)并单击它失败的方式与找到UiObject并单击两次的测试相同。这意味着对象查询的数据必须存储在设备上,因为重置UIautomator没有任何区别。
答案 3 :(得分:1)
我有同样的问题,看起来像寻找具有相同文本的另一个UI元素。我正在尝试自动创建一个警报但是当时间是例如下午4:45。 Uiautomator将点击右键。
clickByText("4");
clickByText("4");
clickByText("5");
clickByText("PM");
clickByText("OK");
private void clickByText(String text) throws UiObjectNotFoundException {
UiObject obj = new UiObject(new UiSelector().text(text));
obj.click();
}
以下是第一个“4”点击的日志:
07-04 16:54:05.259:I / QueryController(25605):匹配选择器: UiSelector [TEXT = 4] &lt;&lt; ==&gt;&gt; [android.view.accessibility.AccessibilityNodeInfo@592f1; boundsInParent:Rect(0,0 - 202,129); boundsInScreen:Rect(56,508 - 258,637); packageName:com.android.deskclock; className: android.widget.Button; text:4 ; contentDescription:null;可检查的:假的;检查:false;可聚焦:真实;专注:虚假; 选中:false; clickable:true; longClickable:false;启用:true; 密码:false;可滚动的:false; [ACTION_FOCUS,ACTION_SELECT, ACTION_CLEAR_SELECTION,ACTION_CLICK,ACTION_ACCESSIBILITY_FOCUS, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY]
以下是第二次“4”点击的日志:
07-04 16:54:07.798:I / QueryController(25605):匹配选择器: UiSelector [TEXT = 4] &lt;&lt; ==&gt;&gt; [android.view.accessibility.AccessibilityNodeInfo@5bffd; boundsInParent:Rect(0,0-66,90); boundsInScreen:Rect(191,264 - 257,354); packageName:com.android.deskclock;班级名称: 的 android.widget.TextView; text:4 ; contentDescription:null;可检查的:假的;检查:false;焦点:虚假;专注:虚假; 选中:false;可点击的:false; longClickable:false;启用: 真正;密码:false;可滚动的:false; [ACTION_SELECT, ACTION_CLEAR_SELECTION,ACTION_ACCESSIBILITY_FOCUS, ACTION_NEXT_AT_MOVEMENT_GRANULARITY, ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY]
我们可以看到一个是点击右边的android.widget.Button,第二个点击它寻找android.widget.TextView。
答案 4 :(得分:0)
创建一个UiObject for 3按钮并单击两次。下面是片段
UiObject three = new UiObject(new UiSelector().text("3"));
three.click();
three.click();