如何在Android仪器测试中检查工具栏标题?

19

我在YouTube上发现了一个非常好的仪器测试教程:高级Android Espresso。我从那里获取了代码,并做了一些小调整以适应我的需求。

import static android.support.test.InstrumentationRegistry.getInstrumentation;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withChild;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.core.AllOf.allOf;

...

@Test
public void checkToolbarTitle() {
    String toolbarTitile = getInstrumentation().getTargetContext().getString(R.string.my_bus_stops);
    onView(allOf(isAssignableFrom(TextView.class), withParent(isAssignableFrom(Toolbar.class)))).check(matches(withText(toolbarTitile)));
}

不幸的是,它对我没有用。测试失败并显示:

android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (is assignable from class: class android.widget.TextView and has parent matching: is assignable from class: class android.widget.Toolbar)

它有什么问题?我该如何用其他方式进行测试?

5个回答

33

这对我有用:

onView(allOf(instanceOf(TextView.class), withParent(withId(R.id.toolbar))))
    .check(matches(withText("toolbarTitile")));

2
这对我没用。正如Grzegorz Bielanski发布的那样,它是导入的问题。instanceOf无法解决。 - Brian S
只是好奇,为什么你要给我点踩?它对大多数情况都有效(请看投票数量),而它在你这里不起作用并不意味着这个答案是错误的。 - denys
我怎么知道它适用于“大多数情况”。我的经验是,在Android上运行的内容会随着版本的更迭而发生变化,今天的相关答案不一定适用于明天。 - Brian S
@gr envoy 你如何知道你的经验和观点对这个问题是有价值的呢?如果它对你不起作用,就不要进行负面评价,留下评论即可。你应该先欣赏别人的努力。 - denys
@denys 我给这个答案点了赞。这个方法对我很有效。当我遇到类似问题时,我发现了这个答案。而且这个答案在一年之后仍然可用。这就让人怀疑 GR Envoy 的假设,即它明天可能失效。 - ant2009

13

解决方案

这种方法是可行的。正如Chiu-Ki Chan在她的教程中所写,您可以“定位到一个特定的视图”。 但是,您必须确保导入了正确的工具栏:

import  android.support.v7.widget.Toolbar;

而不是:

import android.widget.Toolbar;

13

这里是一种替代方案(并且更为惯用):

onView(withId(R.id.toolbar)).check(matches(hasDescendant(withText(toolbarTitle))))

7
如果您正在使用ActionBar而不是Toolbar,请使用以下代码:
onView(allOf(instanceOf(TextView.class), 
     withParent(withResourceName("action_bar"))))
        .check(matches(withText("My ActionBar title")));

注意:要快速添加这些方法的导入,请将闪烁的光标放在未解决的方法上,然后执行Android Studio ➔ 帮助查找操作 ➔ 搜索"show context action""show intention action" ➔ 点击结果选项 ➔ 弹出窗口将出现 ➔ 点击"Import static method ..."。您还可以为 "显示上下文操作" 分配键盘快捷方式。更多信息在此处。另一种方法是在设置中启用"实时添加未歧义的导入"

6

我不记得这是我自己写的还是在某处找到的,但这就是我检查工具栏标题的方法:

public static Matcher<View> withToolbarTitle(CharSequence title) {
    return withToolbarTitle(is(title));
}

public static Matcher<View> withToolbarTitle(final Matcher<CharSequence> textMatcher) {
    return new BoundedMatcher<View, Toolbar>(Toolbar.class) {
        @Override
        public boolean matchesSafely(Toolbar toolbar) {
            return textMatcher.matches(toolbar.getTitle());
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("with toolbar title: ");
            textMatcher.describeTo(description);
        }
    };
}

这适用于所有情况。示例断言: onView(withId(R.id.toolbar))。check(matches(withToolbarTitle(“title”)));

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