如何在父视图下测试带有文本的自定义视图是否为子项?

时间:2016-10-04 14:32:17

标签: android android-espresso

我是TDD和Espresso的新手。我有以下用户故事来简化我的解释:

  

用户从列表中选择一个标签。选择后,显示上一个活动中的选定标签。

这很直截了当。我来自活动A,它会启动活动B。它是在活动B上我从中选择标签。如果我按提交,则标记将显示在活动A上。问题是,我有一个继承自TagViewGroup的自定义LinearLayout和一个特定于该组TagView的父子。这些都是非常简单的布局。

我写了以下测试:

    @Test
    public void shouldPickAndBindTagToNote()
    {
        onView(withId(R.id.edittext_description_minimized)).perform(click());
        onView(withId(R.id.linearlayout_add_note_maximize)).check(matches(isDisplayed()));
        onView(withId(R.id.relativelayout_quick_action_button)).check(matches(isDisplayed()));
        onView(withId(R.id.imagebutton_tag)).perform(click());
        onView(withId(R.id.coordinatorlayout_tag_list)).check(matches(isDisplayed()));

        onView(withText("TODO")).perform(click());
        onView(withText("Critical")).perform(click());
        onView(withText("For Tomorrow")).perform(click());

        onView(withId(R.id.fab_tag_list)).perform(click());
        onView(withId(R.id.tagviewgroup_note_tags)).check(matches(isDisplayed()));


// This part checks if the selected tag TODO, Critical, Reminders are on the TagViewGroup        
   onView(withId(R.id.tagviewgroup_note_tags)).check(matches(NoteTagMatcher.hasTag(is("TODO"))));
        onView(withId(R.id.tagviewgroup_note_tags)).check(matches(NoteTagMatcher.hasTag(is("Reminders"))));
        onView(withId(R.id.tagviewgroup_note_tags)).check(matches(NoteTagMatcher.hasTag(is("For Tomorrow"))));
    }

这是我的自定义匹配器:

public class NoteTagMatcher
{
    public static Matcher<View> hasTag(final Matcher<String> tagName)
    {
        return new TypeSafeMatcher<View>()
        {
            @Override
            protected boolean matchesSafely(View item)
            {
                if(!(item instanceof TagViewGroup))
                    return false;

                TagViewGroup tvg = (TagViewGroup) item;
                int c = tvg.getChildCount();

                for(int i = 0; i < c; ++i)
                {
                    View v = tvg.getChildAt(i);

                    if(!(v instanceof TagView)) continue;

                    TagView tv = (TagView) v;

                    if(tagName.matches(tv.getText()))
                        return true;

                    return false;
                }

                return false;
            }

            @Override
            public void describeTo(Description description)
            {

            }
        };
    }
}

此测试总是因某种原因失败:

android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: '' doesn't match the selected view.
Expected:
Got: "TagViewGroup{id=2131624148, res-name=tagviewgroup_note_tags, visibility=VISIBLE, width=468, height=72, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, 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=107.0, child-count=3}"

我不明白这个错误。但我能够用这个简单的方法来检查它,我刚刚意识到:

onView(withText("TODO")).check(matches(isDisplayed()));
onView(withText("Critical")).check(matches(isDisplayed()));
onView(withText("For Tomorrow")).check(matches(isDisplayed()));

这很简单,需要较少的hackish代码,并且非常容易阅读和理解,但我想要一点挑战,所以我加倍努力实现我自己的匹配器,并试着看看我是否可以检查我的自定义{{在TagView

下确实存在一个字符串TODO

正如我所说,我想要做的是测试带有特定文字的所选标记(TagViewGroup)是否出现在我的自定义TagViewViewGroup)下。鉴于我的自定义匹配器,显然不起作用,我怎么能这样做?我犯了什么不法行为?

关于如何正确测试这个问题的任何想法?

谢谢!

0 个答案:

没有答案