Java 如何使用Google UiAutomator按两次按钮?
我有下面的脚本,用于在Android中使用UiAutomator在计算器中键入'33'。然而,只有第一个“3”被接受,第二个新闻被完全忽略Java 如何使用Google UiAutomator按两次按钮?,java,android,automated-tests,avd,android-uiautomator,Java,Android,Automated Tests,Avd,Android Uiautomator,我有下面的脚本,用于在Android中使用UiAutomator在计算器中键入'33'。然而,只有第一个“3”被接受,第二个新闻被完全忽略 import com.android.uiautomator.core.*; import com.android.uiautomator.testrunner.UiAutomatorTestCase; public class MyFirstUiAutomatorTest extends UiAutomatorTestCase { UiObjec
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;
}
然而,这对我来说也不起作用:只有第一个“3”出现,而第二个被忽略,即使两次单击明显位于同一位置,因为rect:
输出位置是相同的。如果我使用自己的桌面鼠标手动单击“3”两次,则两个3都显示正常
我还尝试在两次单击之间添加一个两秒钟的
Thread.sleep()
,但仍然只有一个'3'出现在我面前。我也有同样的问题,看起来它在寻找另一个具有相同文本的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][android.view.accessibility。AccessibilityNodeInfo@592f1;
boundsInParent:Rect(0,0-202129);boundsInScreen:Rect(56508-258637);packageName:com.android.deskclock;className:android.widget.Button;文本:4;内容描述:null;可检查:false;已检查:false;可聚焦:true;
所选:false;可点击:true;可点击:false;已启用:true;
密码:false;可滚动:false;[ACTION\u FOCUS,ACTION\u SELECT,
操作\u清除\u选择、操作\u单击、操作\u可访问性\u焦点、,
行动(下一步)行动(下一步)(下一步)(下一步)(下一步)(下一步),
动作(上一次)(移动)(粒度)]]
这是第二次“4”点击的日志:
07-04 16:54:07.798:I/QueryController(25605):匹配的选择器:
UiSelector[TEXT=4][android.view.accessibility。AccessibilityNodeInfo@5bffd;
boundsInParent:Rect(0,0-66,90);boundsInScreen:Rect(191264-257354);packageName:com.android.deskclock;类名:
android.widget.TextView;文本:4;内容描述:null;可检查:false;已检查:false;可聚焦:false;聚焦:false;
所选:false;可点击:false;可点击:false;已启用:
true;密码:false;可滚动:false;[ACTION\u SELECT,
行动\u清除\u选择,行动\u可访问性\u焦点,
行动(下一步)在行动(下一步)粒度,
动作(上一次)(移动)(粒度)]]
我们可以看到,其中一个正在单击正确的android.widget.Button,第二个单击它查找android.widget.TextView。我发现了一个解决问题的小技巧。每次运行测试时都要获得边界,这样它就不会以设备为中心,并且可以动态适应
UiObject obj1 = new UiObject(new UiSelector().text("4"));
Rect four = obj1.getBounds();
getUiDevice().click(four.centerX(), four.centerY());
尝试按文本和类进行搜索,而不仅仅是按文本进行搜索。 下面是一个这样做的示例方法
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检查不同UIObject的类名和其他属性
这在我的4.2.2设备上运行,但我正在下载4.1.2在那里测试它
我在4.1.2 AVD上试用过,它在我的Windows机器上运行。这个问题似乎是在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按钮创建UiObject并单击两次。下面是代码段
UiObject three = new UiObject(new UiSelector().text("3"));
three.click();
three.click();
这听起来是一个很好的解决办法,但我刚刚尝试过,但它对我不起作用。如果我手动单击“3”按钮两次,则会看到“33”,但如果我让UiAutomator使用
getUiDevice()。单击()
在同一位置单击两次,则仍然会看到单个“3”。这一点,我甚至在两次点击之间添加了一个Thread.sleep(2000)
。我创建了一个名为setUpDigit()
的方法,在这里我设置了我的UIobjectUIobject zero=new UIobject(new UiSelector().text(“0”)代码>和我有一个全局值Rzero,它是在相同的方法setUpDigit()中设置的代码>然后我有一个使用全局值Rzero的开关,并单击右按钮getUiDevice()。单击(Rzero.centerX(),Rzero.centerY())代码>棘手的部分是何时调用setUpDigit()。信息技术
UiObject three = new UiObject(new UiSelector().text("3"));
three.click();
three.click();