2

我刚刚遇到了 Robotium 的障碍,试图通过功能测试重现错误。在登录期间从用户名字段移动到密码字段时,我的活动未设置为正确处理“下一个”键。我在谷歌上搜索了一下,我无法找到解决方案。我在我的 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 发送回车键,但它们都没有模拟“下一个”键。帮助!

4

2 回答 2

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);
}
于 2013-01-14T18:49:55.200 回答
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();
}

这应该总是返回,但如果你愿意,你可以为第二个等待添加超时。

于 2013-10-08T17:04:00.733 回答