How to catch a View with Tag by Espresso in Androi

2019-06-17 03:01发布

问题:

I have a PinCodeView that extends LinearLayout. I have following code in my init() method. DigitEditText extends EditText and just accepts one digit. This view will be used to receive confirmation code which has 4 digits long.

private void init()
{
    ...

    for (int i = 0; i < 4; i++)
    {
        DigitEditText digitView = getDigitInput();
        digitView.setTag(R.id.etPinCodeView, i); // uses for Espresso testing
        digitView.setKeyEventCallback(this);
        ...
}

I have created res/values/ids.xml and this is its content:

<resources>
    <item name="etPinCodeView" type="id"/>
</resources>

Now, in Espresso I want to catch each DigitEditText and put a digit in it. How I'm able to do that? I see there are two methodes, withTagKey() and withTagValue() but I have no idea how to get them into work.

I thought something like this might work but seems I'm not able to assign 0 into withTagValue().

onView(allOf(withTagKey(R.id.etPinCodeView), withTagValue(matches(0)))).perform(typeText("2"));

回答1:

Since withTagValue needs an instance of org.hamcrest.Matcher as an argument, we can create a simple one using the Matcher.is method to find views with a certain tag in your expresso test:

String tagValue = "lorem impsum";
ViewInteraction viewWithTagVI = onView(withTagValue(is((Object) tagValue)));


回答2:

I solved my problem with this trick. Hope it saves some times for you.

First I used Id rather than tag.

for (int i = 0; i < 4; i++)
    {
        DigitEditText digitView = getDigitInput();
        digitView.setId(R.id.etPinCodeView + i); // uses for Espresso testing
        digitView.setKeyEventCallback(this);
        ...

And this is test for it:

onView(withId(R.id.etPinCodeView + 0)).perform(typeText("2"));
onView(withId(R.id.etPinCodeView + 1)).perform(typeText("0"));
onView(withId(R.id.etPinCodeView + 2)).perform(typeText("1"));
onView(withId(R.id.etPinCodeView + 3)).perform(typeText("6"));