如何测试菜单

13

我需要用单元测试来覆盖菜单功能,但是我无法获取菜单对象。

以下测试用例失败了(mMenu为空):

sendKeys(KeyEvent.KEYCODE_MENU);
mMenu = (Menu) mActivity.findViewById(com.###.###.R.id.main_menu);
assertNotNull(mMenu);

请给予建议。谢谢。

5个回答

22

我遇到了同样的情况,并在我的ActivityInstrumentationTestCase实现中想出了以下(非常简单)的解决方案:

...
ActivityMonitor am = getInstrumentation().addMonitor(LoginActivity.class.getName(), null, false);

// Click the menu option
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
getInstrumentation().invokeMenuActionSync(mActivity, R.id.logout, 0);

Activity a = getInstrumentation().waitForMonitorWithTimeout(am, 1000);
assertEquals(true, getInstrumentation().checkMonitorHit(am, 1));
a.finish();
...

这段代码实现了三个功能:

  1. 点击菜单选项,
  2. 确保在单击菜单选项后我们进入适当的活动,并且
  3. 结束已启动的活动(对于接下来的测试非常重要)。

希望这可以帮到您。


这是一个有用的答案和代码片段,最重要的是它强调了在调用菜单操作之前必须先发送“KeyEvent.KEYCODE_MENU”。回想起来很明显,我猜 - 你必须先显示菜单才能调用其中的项目。 - Matt Green
1
就我个人而言,我使用getInstrumentation().invokeMenuActionSync()而不需要先调用sendKeyDownUpSync(),这也能正常工作。请参见此问题的答案:http://stackoverflow.com/questions/5209154/test-menu-items - karni
我注意到如果你想测试在onPrepareOptionMenu中完成的工作的结果下,调用sendKeyDownUpSync是必要的,以便invokeMenuActionSync返回true。如果没有这个调用,onPrepareOptionsMenu将不会被调用。 - mtotschnig

2

你想要测试什么?是菜单项是否执行正确的操作吗?

你可以调用Activity.openOptionsMenu()来打开菜单,并通过重写onMenu方法之一获取菜单的引用。此时,你可以使用Menu.performIdentifierAction来选择菜单项。


1
是的,我需要检查所有菜单和子菜单项是否执行正确的操作。sendKeys(KeyEvent.KEYCODE_MENU)可以正常工作,我可以在模拟器上看到菜单(如果调用Activity.openOptionsMenu(),则无法看到它)。您的意思是我需要在目标应用程序中重写onMenuOpened并在活动内保存菜单引用吗? 也许有一种方法可以不触及目标应用程序? - cement

2
如果你想进行UI、系统或功能测试,我建议你使用Robotium。然后你可以使用sendKey(Solo.MENU)并使用clickOnText()或clickOnView()来点击菜单项。完成后,你可以断言正确的行为。仅仅断言它不应为空是不够的。你应该了解一下Robotium,它适用于像这样的测试。

1
    Activity act =launchActivity(intent);

    MenuBuilder builder=new MenuBuilder(mInst.getTargetContext());

    act.onCreateOptionsMenu(builder);



    act.onPrepareOptionsMenu(builder);

    Log.i(TAG, "BuilderSize: "+builder.size());
    int visible=0;
    for(int i=0;i<builder.size();i++)
    {
        MenuItem item=builder.getItem(i);

        if(item.isVisible()&& item.isEnabled())
        {
            Log.i(TAG, item.getTitle().toString());
            visible++;
        }
    }
    act.finish();

0

使用仪器测试菜单项的按压。

这是我的一个示例测试用例,调用“设置”菜单,启动另一个活动。

public void testCanGoToSettings() {
    final MainActivity activity = getActivity();

    Instrumentation.ActivityMonitor am = getInstrumentation().addMonitor(ConfigureActivity.class.getName(),
            null /* result */, true /* block */);

    getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
    getInstrumentation().invokeMenuActionSync(activity, R.id.menu_settings, 0 /* flags */);

            /* if not block in addMonitor() above, then comment out this...
    Activity a = getInstrumentation().waitForMonitorWithTimeout(am, 1000);
    a.finish();
            */ 

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接