[英]Android Expresso verifying Context Menu and actionBar items
我有一個列表,其中每一行都包含一個名稱和一個調用選項的上下文菜單的按鈕。 我想編寫一個驗證以下內容的測試
當長時間選擇該項時,我還想測試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.