簡體   English   中英

Android Expresso驗證上下文菜單和actionBar項

[英]Android Expresso verifying Context Menu and actionBar items

我有一個列表,其中每一行都包含一個名稱和一個調用選項的上下文菜單的按鈕。 我想編寫一個驗證以下內容的測試

  1. 上下文菜單包含正確數量的項目
  2. 上下文菜單包含正確的值
  3. 上下文菜單不包含任何不必要的選項(上面的檢查1和2將測試這種情況)

當長時間選擇該項時,我還想測試actionBar和actionBar溢出菜單的內容。

對於這兩個測試,我都可以編寫檢查以確保顯示的視圖元素具有正確的“標簽”(即使用onView(withText(this.elementText)查找視圖))。但是,我有2個動作具有相同的標簽,但不同的ID,我需要確保上下文菜單/長按菜單中的操作正確。

我無法在上下文菜單的菜單中使用在XML中指定的ID,因為Android的上下文菜單視圖沒有這些ID,而是包含一個內部Android ID(請參見下面的屏幕截圖)。 在此處輸入圖片說明

當我使用Robotium編寫測試時,我必須獲取某種類型的所有當前視圖,並通過它們進行解析以檢查它們是否為actionBar項,請參見下面的示例代碼。

public static List<MenuItemImpl> getLongClickMenuItems(String itemName) {
    List<MenuItemImpl> menuItems = new ArrayList<>();

    // long select the item
    solo.clickLongOnText(itemName);

    // get the children of the of the long click action bar
    ArrayList<ActionMenuView> outViews = solo.getCurrentViews(ActionMenuView.class, solo.getView(R.id.action_mode_bar));

    if (!outViews.isEmpty()) {
        // get the first child which contains the action bar actions
        ActionMenuView actionMenuView = outViews.get(0);
        // loop over the children of the ActionMenuView which is the individual ActionMenuItemViews
        // only a few fit will fit on the actionBar, others will be in the overflow menu
        int count = actionMenuView.getChildCount();
        for (int i = 0; i < count; i++) {
            View child = actionMenuView.getChildAt(i);

            if (child instanceof ActionMenuItemView) {
                menuItems.add(((ActionMenuItemView) child).getItemData());
            } else {
                // this is the more button, click on it and wait for the popup window
                // which will contain a list of ListMenuItemView
                // As we are using the AppCompat the actionBar's menu items are the
                // the AppCompat's ListMenuItemView (android.support.v7.view.menu.ListMenuItemView)
                // In the context menu, the menu items are Android's native ListMenuItemView
                // (com.android.internal.view.menu.ListMenuItemView)
                solo.clickOnView(child);
                solo.waitForView(ListMenuItemView.class);
                ArrayList<ListMenuItemView> popupItems = solo.getCurrentViews(ListMenuItemView.class);
                for (ListMenuItemView lvItem : popupItems) {
                    menuItems.add(lvItem.getItemData());
                }

                // close the more button actions menu
                solo.goBack();
            }
        }
    }

    // get out of long click mode
    solo.goBack();

    return menuItems;
}

有誰知道我如何使用Expresso獲得“上下文行”菜單項的列表。

有誰知道我如何使用Expresso獲得actionBar項目(包括溢出菜單中的所有項目)?

如果我正確理解了您的問題,那么您應該可以在onData()方法上與上下文菜單進行交互,因為它們只是AdapterViews (注意,屏幕快照中的彈出窗口是ListPopupWindow$DropDownListView )。

因此,您應該能夠執行以下操作:

onView(withText("Item Label")).perform(longClick());
final int expectedItemCount = 10;

// Now the floating popup should be showing,
// first assert it has the expected item count

onView(isAssignableFrom(AdapterView.class))
.check(matches(withItemCount(expectedItemCount)));

// Now assert each entry (which should just be a string) is shown correctly
for (int i = 0; i < expectedItemCount; i++) {
    String expectedItemText = getExpectedItemTextForIndex(i);
    onData(instanceOf(String.class)).atPosition(i)
        .check(matches(withText(expectedItemText)));
}

上面的withItemCount匹配器是一個簡單的匹配器,它針對給定的適配器視圖的適配器計數進行斷言:

public static Matcher<View> withNumberOfItems(final int itemsCount) {
    return new BoundedMatcher<View, AdapterView>(AdapterView.class) {
        @Override
        public void describeTo(Description description) {
            description.appendText("with number of items: " + itemsCount);
        }

        @Override
        protected boolean matchesSafely(AdapterView item) {
            return item.getAdapter().getCount() == itemsCount;
        }
    };
}

我認為相同的概念應適用於操作欄溢出菜單。

我不清楚您的意思是:

對於這兩個測試,我都可以編寫檢查以確保顯示的視圖元素具有正確的“標簽”(即使用onView(withText(this.elementText)查找視圖))。但是,我有2個動作具有相同的標簽,但不同的ID,我需要確保上下文菜單/長按菜單中的操作正確。

但是atPosition應該可以為您提供您對列表感興趣的視圖,並且如果需要在列表中的給定項目中作為子視圖定位,則可以添加onChildView

希望有幫助!

非常感謝dominicoder給我這個問題的答案。 在他們的答復上工作,我設法使它起作用。

而不是使用“ isAssignableFrom(AdapterView.class)”,而是使用“ isAssignableFrom(ListView.class)”。

然后,我使用提供的完全相同的匹配器“ dominicoder”來驗證上下文菜單項的數量。

使用“ dominicoder的”樣本匹配器,我自己編寫了一個代碼,用於檢查ListView中某個位置的MenuItem,並且可以比較ID以確保其期望的ID。

public boolean verifyRowContextMenuContents(String name, MyActionObject[] actions){
    // invoke the row context menu
    clickRowActionButton(name);

    // The Context Menu Popup contains a ListView
    int expectedItemCount = actions.length;

    // first check the Popup's listView contains the correct number of items
    onView(isAssignableFrom(ListView.class))
            .check(matches(correctNumberOfItems(expectedItemCount)));

    // now check the order and the IDs of each action in the menu is the expected action
    for (int i = 0; i < expectedItemCount; i++) {
        onView(isAssignableFrom(ListView.class))
                .check(matches(correctMenuId(i, actions[i].getId())));
    }

    // close the context menu
    pressBack();

    return true;
}

private static Matcher<View> correctNumberOfItems(final int itemsCount) {
    return new BoundedMatcher<View, ListView>(ListView.class) {
        @Override
        public void describeTo(Description description) {
            description.appendText("with number of items: " + itemsCount);
        }

        @Override
        protected boolean matchesSafely(ListView listView) {
            ListAdapter adapter = listView.getAdapter();
            return adapter.getCount() == itemsCount;
        }
    };
}

private static Matcher<View> correctMenuId(final int position, final int expectedId) {
    return new BoundedMatcher<View, ListView>(ListView.class) {
        @Override
        public void describeTo(Description description) {
            description.appendText("with position : " + position + " expecting id: " + expectedId);
        }

        @Override
        protected boolean matchesSafely(ListView listView) {
            ListAdapter adapter = listView.getAdapter();
            Object obj = adapter.getItem(position);
            if (obj instanceof MenuItem){
                MenuItem menuItem = (MenuItem)obj;
                return menuItem.getItemId() == expectedId;
            }
            return false;
        }
    };
}   

使用此代碼,我可以檢查上下文菜單是否包含正確數量的菜單項,並且菜單中的項是否是我期望的(使用ID驗證)和期望的順序。

非常感謝“ dominicoder”。 很遺憾您不能將兩個答案都標記為正確答案,就像您實際上給了我正確答案一樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM