我只是想与Robotium试图通过功能测试重现错误。我的活动未设置为正确处理" next"在登录期间从用户名字段移动到密码字段时的密钥。我谷歌搜索了一下,我无法解决问题。我在Galaxy Nexus上试过这个:
solo.clearEditText(0);
solo.enterText(0, Constants.TEST_ACCOUNT_1.getUsername());
solo.clickOnEditText(0);
solo.clickOnScreen(672,1132);
solo.clickOnEditText(0);
solo.sleep(15000);
solo.enterText(1, Constants.TEST_ACCOUNT_1.getPassword());
想法是单击文本字段以抬起键盘,然后尝试单击下一个按钮,但编辑文本字段中的单击不会抬起键盘。我也试过发送回车键,我尝试使用FLAG_EDITOR_ACTION发送回车键,它们都没有模拟"下一步"键。救命啊!
答案 0 :(得分:6)
Robotium似乎没有显示键盘的方法。此外,似乎键盘在Robotium可以与之交互的范围之外运行,因为clickOnText()
即使可见,也不会按下软键盘按钮。因此,这个答案将会是一个黑客攻击。
解决方案有两个重要部分。首先,虽然我们无法使用dispatchKeyEvent
直接单击IME Next按钮,但我们可以使用其他键盘按钮,我们可以使用EditText.onEditorAction(EditorInfo.IME_ACTION_NEXT)
触发其回调。这将允许我们跳到下一个EditText。其次,触发此回调属于“与UI交互”的类别,因此我们必须从运行Robotium的线程转回主线程以进行调用。我们将使用Activity.runOnUiThread()
来实现此目标。
这是一个如何为我工作的例子:
public void testImeNext() throws Exception
{
//Grab a reference to your EditText. This code grabs the first Edit Text in the Activity
//Alternatively, you can get the EditText by resource id or using a method like getCurrentEditTexts()
//Make sure it's final, we'll need it in a nested block of code.
final EditText editText = solo.getEditText(0);
//Create a runnable which triggers the onEditorAction callback
Runnable runnable = new Runnable()
{
@Override
public void run()
{
editText.onEditorAction(EditorInfo.IME_ACTION_NEXT);
}
};
//Use Solo to get the current activity, and pass our runnable to the UI thread.
solo.getCurrentActivity().runOnUiThread(runnable);
}
答案 1 :(得分:4)
在另一个答案的基础上,我编写了一个模拟IME按钮按下的方法,直到UI线程上的请求完成后才返回。
/**
* This will send the NEXT action to simulate pressing next on the keyboard.
* Because it has to be run on the UI thread we use a barrier to block and
* stop this request returning until the action is complete.
**/
private void sendIMENext(final EditText editText) throws Exception {
final CyclicBarrier barrier = new CyclicBarrier(2);
Runnable runnable = new Runnable() {
@Override
public void run() {
editText.onEditorAction(EditorInfo.IME_ACTION_NEXT);
try {
barrier.await();
}
catch (Exception e) {
Log.e("MainActivityTest", "Interupted on UI thread pressing IME next", e);
}
}
};
//Use Solo to get the current activity, and pass our runnable to the UI thread.
solo.getCurrentActivity().runOnUiThread(runnable);
// Waits until the barrier is met in the runnable
barrier.await();
}
这应该总是返回,但如果你愿意,可以在第二个 await 中添加超时。