Android 如何使用Espresso检查BottomNavigationItemView?
Android 如何使用Espresso检查BottomNavigationItemView?,android,android-espresso,android-testing,bottomnavigationview,Android,Android Espresso,Android Testing,Bottomnavigationview,BottomNavigationItemView实现ItemView接口,该接口具有setChecked()方法 我试图用Espresso断言选中了一个itemView,但我得到了相同的错误,无论我的期望值是什么,isChecked()或isnotched() 我的测试: ViewInteraction buttonHome = onView( allOf(withId(R.id.bottomHome), childAtPosition(
BottomNavigationItemView
实现ItemView
接口,该接口具有setChecked()
方法
我试图用Espresso断言选中了一个itemView,但我得到了相同的错误,无论我的期望值是什么,isChecked()
或isnotched()
我的测试:
ViewInteraction buttonHome = onView(
allOf(withId(R.id.bottomHome),
childAtPosition(
childAtPosition(
withId(R.id.bottom_navigation),
0),
0),
isDisplayed()));
buttonHome.check(matches(isNotChecked()));
错误消息
android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with checkbox state: is <true>' doesn't match the selected view.
Expected: with checkbox state: is <true>
Got: "BottomNavigationItemView{id=2131493015, res-name=bottomHome, visibility=VISIBLE, width=360, height=168, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=2}"
android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError:“with checkbox state:is”与所选视图不匹配。
应为:复选框状态为
获得:“BottomNavigationItemView{id=2131493015,res name=bottomHome,visibility=VISIBLE,width=360,height=168,has focus=false,has focusable=false,has window focus=true,is clickable=true,is enabled=true,is focusable=false,is layout request=false,is selected=false,root is layout request=false,has input connection=false,x=0.0,child count=2}”
如何断言BottomNavigationItemView
是BottomNavigationView
的当前选定项?这两个isChecked()
和isnotcked()
都期望由视图实现接口
此外,BottomNavigationItemView
将其选中状态隐藏在itemData
字段中。这意味着开箱即用的Espresso不支持此类检查。幸运的是,Espresso是一个非常可扩展的框架,您可以轻松地向其添加功能。在这种情况下,我们需要编写一个自定义匹配器来完成此操作检查
上述匹配器的实现可能如下所示:
public static Matcher<View> withBottomNavItemCheckedStatus(final boolean isChecked) {
return new BoundedMatcher<View, BottomNavigationItemView>(BottomNavigationItemView.class) {
boolean triedMatching;
@Override
public void describeTo(Description description) {
if (triedMatching) {
description.appendText("with BottomNavigationItem check status: " + String.valueOf(isChecked));
description.appendText("But was: " + String.valueOf(!isChecked));
}
}
@Override
protected boolean matchesSafely(BottomNavigationItemView item) {
triedMatching = true;
return item.getItemData().isChecked() == isChecked;
}
};
}
isChecked()
和isnotcked()
都希望通过视图实现接口
此外,BottomNavigationItemView
将其选中状态隐藏在itemData
字段中。这意味着开箱即用的Espresso不支持此类检查。幸运的是,Espresso是一个非常可扩展的框架,您可以轻松地向其添加功能。在这种情况下,我们需要编写一个自定义匹配器来完成此操作检查
上述匹配器的实现可能如下所示:
public static Matcher<View> withBottomNavItemCheckedStatus(final boolean isChecked) {
return new BoundedMatcher<View, BottomNavigationItemView>(BottomNavigationItemView.class) {
boolean triedMatching;
@Override
public void describeTo(Description description) {
if (triedMatching) {
description.appendText("with BottomNavigationItem check status: " + String.valueOf(isChecked));
description.appendText("But was: " + String.valueOf(!isChecked));
}
}
@Override
protected boolean matchesSafely(BottomNavigationItemView item) {
triedMatching = true;
return item.getItemData().isChecked() == isChecked;
}
};
}
基于上述答案和评论,我创建了这个匹配器:
import android.support.design.widget.BottomNavigationView;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.util.HashSet;
import java.util.Set;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
/**
* Custom matchers for Espresso.
*/
public class EspressoUtils {
/**
* Checks that {@link BottomNavigationView} contains an item with provided id and that it is
* checked.
*
* @param id of the item to find in the navigation view
* @return a matcher that returns true if the item was found and checked
*/
public static Matcher<View> hasCheckedItem(final int id) {
return new BoundedMatcher<View, BottomNavigationView>(BottomNavigationView.class) {
Set<Integer> checkedIds = new HashSet<>();
boolean itemFound = false;
boolean triedMatching = false;
@Override public void describeTo(Description description) {
if (!triedMatching) {
description.appendText("BottomNavigationView");
return;
}
description.appendText("BottomNavigationView to have a checked item with id=");
description.appendValue(id);
if (itemFound) {
description.appendText(", but selection was=");
description.appendValue(checkedIds);
} else {
description.appendText(", but it doesn't have an item with such id");
}
}
@Override protected boolean matchesSafely(BottomNavigationView navigationView) {
triedMatching = true;
final Menu menu = navigationView.getMenu();
for (int i = 0; i < menu.size(); i++) {
final MenuItem item = menu.getItem(i);
if (item.isChecked()) {
checkedIds.add(item.getItemId());
}
if (item.getItemId() == id) {
itemFound = true;
}
}
return checkedIds.contains(id);
}
};
}
}
基于上述答案和评论,我创建了这个匹配器:
import android.support.design.widget.BottomNavigationView;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.util.HashSet;
import java.util.Set;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
/**
* Custom matchers for Espresso.
*/
public class EspressoUtils {
/**
* Checks that {@link BottomNavigationView} contains an item with provided id and that it is
* checked.
*
* @param id of the item to find in the navigation view
* @return a matcher that returns true if the item was found and checked
*/
public static Matcher<View> hasCheckedItem(final int id) {
return new BoundedMatcher<View, BottomNavigationView>(BottomNavigationView.class) {
Set<Integer> checkedIds = new HashSet<>();
boolean itemFound = false;
boolean triedMatching = false;
@Override public void describeTo(Description description) {
if (!triedMatching) {
description.appendText("BottomNavigationView");
return;
}
description.appendText("BottomNavigationView to have a checked item with id=");
description.appendValue(id);
if (itemFound) {
description.appendText(", but selection was=");
description.appendValue(checkedIds);
} else {
description.appendText(", but it doesn't have an item with such id");
}
}
@Override protected boolean matchesSafely(BottomNavigationView navigationView) {
triedMatching = true;
final Menu menu = navigationView.getMenu();
for (int i = 0; i < menu.size(); i++) {
final MenuItem item = menu.getItem(i);
if (item.isChecked()) {
checkedIds.add(item.getItemId());
}
if (item.getItemId() == id) {
itemFound = true;
}
}
return checkedIds.contains(id);
}
};
}
}
在这种情况下,可能尝试使用经典JUnit断言而不是Espresso断言。我的意思是:
assertEquals(((BottomNavigationItemView)findViewById(R.id.bottomHome)).isChecked(),true);
在这种情况下,可能尝试使用经典JUnit断言而不是Espresso断言。我的意思是:assertEquals(((BottomNavigationItemView)findViewById)(R.id.bottomHome)).isChecked(),true);
NiceMatcher
。请避免使用BottomNavigationItemView
,因为它仅对组id可见。请尝试迭代bottomNavigationView.getChildAt(0)的子级
哪个实现了菜单项
。如果我想点击BottomNavigation的特定项怎么办?很好的匹配器
。请注意,不要使用BottomNavigationItemView
,因为它只对组id可见。尝试迭代bottomNavigationView.getChildAt(0)的子项
哪个实现MenuItem
。如果我想点击底部导航的特定项目怎么办?如果我想点击特定项目?比如说通过索引或描述文本?不确定你的意思,抱歉请看一下:这是关于用浓缩咖啡点击底部导航的项目你看了@arekolek吗?我看不到我想出来…如果我想点击特定的项目?比如说通过索引或描述文本?不确定你的意思,抱歉,请看一看:这是关于用浓缩咖啡点击底部导航的项目你看了@arekolek吗?我想不出来。。。