8

Tôi đang cố gắng kiểm tra bằng cách sử dụng Espresso nếu số lượt xem TextInputLayout của tôi có gợi ý cụ thể. Tôi đã sử dụng một mã số như sau:Làm cách nào để kiểm tra các giá trị TextInputLayout (gợi ý, lỗi, v.v.) bằng cách sử dụng Android Espresso?

Espresso.onView(ViewMatchers.withId(R.id.edit_text_email)) 
    .check(ViewAssertions.matches(
     ViewMatchers.withHint(R.string.edit_text_email_hint))) 

này hoạt động tốt cho EditText quan điểm bình thường, không được bọc trong TextInputLayout. Tuy nhiên khi nó kết thúc tốt đẹp, nó không còn hoạt động nữa.

Tôi đã cố gắng sử dụng giải pháp từ Android Espresso - How to check EditText hint? nhưng vẫn không hoạt động.

Tôi cũng xem xét: https://code.google.com/p/android/issues/detail?id=191261 báo cáo sự cố, nó cho biết cách giải quyết khá dễ dàng bằng cách trỏ đến mã withHint hiện tại, nhưng tôi không thể làm cho nó hoạt động.

Bất kỳ ý tưởng nào để khắc phục vấn đề này?

Trả lời

16

Dưới đây là khớp tùy chỉnh của tôi:

public static Matcher<View> hasTextInputLayoutHintText(final String expectedErrorText) { 
     return new TypeSafeMatcher<View>() { 

      @Override 
      public boolean matchesSafely(View view) { 
       if (!(view instanceof TextInputLayout)) { 
        return false; 
       } 

       CharSequence error = ((TextInputLayout) view).getHint(); 

       if (error == null) { 
        return false; 
       } 

       String hint = error.toString(); 

       return expectedErrorText.equals(hint); 
      } 

      @Override 
      public void describeTo(Description description) { 
      } 
     }; 
    } 
} 

và đây là làm thế nào để sử dụng:

@RunWith(AndroidJUnit4.class) 
public class MainActivityTest { 

    @Rule 
    public ActivityTestRule<MainActivity> mRule = new ActivityTestRule<>(MainActivity.class); 

    @Test 
    public void testMyApp() { 
     onView(withId(R.id.textInputLayout)).check 
       (matches(hasTextInputLayoutErrorText(mRule.getActivity().getString(R.string 
         .app_name)))); 

    } 

Nếu bạn muốn kiểm tra errorText của TextInputLayout, thay đổi dòng này:

 CharSequence error = ((TextInputLayout) view).getHint(); 

với

 CharSequence error = ((TextInputLayout) view).getError(); 

Hy vọng nó sẽ giúp

+0

này hoạt động. Cảm ơn bạn rất nhiều! – Elye

+0

Tôi có thể đặt đối sánh tùy chỉnh hasTextInputLayoutHintText ở đâu? – aleksandrbel

+0

Vì trong mã của tôi, tôi đã đặt lỗi thành TextInputEditText, tôi phải thay đổi TextInputLayout thành TextInputEditText trong trình ghép nối. –

1

Nhiều giải pháp chung chung mà sẽ làm việc với bất kỳ Xem có "getHint" phương pháp:

public static Matcher<View> withCustomHint(final Matcher<String> stringMatcher) { 
    return new BaseMatcher<View>() { 
     @Override 
     public void describeTo(Description description) { 
     } 

     @Override 
     public boolean matches(Object item) { 
      try { 
       Method method = item.getClass().getMethod("getHint"); 
       return stringMatcher.matches(method.invoke(item)); 
      } catch (NoSuchMethodException e) { 
      } catch (InvocationTargetException e) { 
      } catch (IllegalAccessException e) { 
      } 
      return false; 
     } 
    }; 
} 

Cách sử dụng:

onView(withId(R.id.SomeLayout)).check(matches(withCustomHint(is("SomeString")))); 
0

Các giải pháp trên didn' t làm việc cho trường hợp sử dụng của tôi. Tôi muốn tìm TextInputEditText và nhập văn bản vào đó. Đây là giải pháp của tôi:

@VisibleForTesting 
class WithTextInputLayoutHintMatcher @RemoteMsgConstructor 
constructor(@field:RemoteMsgField(order = 0) 
      private val stringMatcher: Matcher<String>) : TypeSafeMatcher<View>() { 

    override fun describeTo(description: Description) { 
     description.appendText("with TextInputLayout hint: ") 
     stringMatcher.describeTo(description) 
    } 

    public override fun matchesSafely(textInputEditText: View): Boolean { 
     if (textInputEditText !is TextInputEditText) return false 

     return stringMatcher.matches((textInputEditText.parent.parent as? TextInputLayout)?.hint) 
    } 
} 

/** 
* Returns a matcher that matches [TextInputEditText] based on it's hint property value. 
* 
* 
* **Note:** View's sugar for `withHint(is("string"))`. 
* 
* @param hintText [String] with the hint text to match 
*/ 
fun withTextInputHint(hintText: String): Matcher<View> { 
    return withTextInputHint(Matchers.`is`(checkNotNull(hintText))) 
} 

/** 
* Returns a matcher that matches a descendant of [TextInputEditText] that is displaying the hint 
* associated with the given resource id. 
* 
* @param resourceId the string resource the text view is expected to have as a hint. 
*/ 
fun withTextInputHint(resourceId: Int): Matcher<View> { 
    return withTextInputHint(getString(resourceId)) 
} 

/** 
* Returns a matcher that matches [TextView]s based on hint property value. 
* 
* 
* **Note:** View's hint property can be `null`, to match against it use ` 
* withHint(nullValue(String.class)` 
* 
* @param stringMatcher [`Matcher 
`](http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matcher.html) * of [String] with text to match 
*/ 
fun withTextInputHint(stringMatcher: Matcher<String>): Matcher<View> { 
    return WithTextInputLayoutHintMatcher(checkNotNull(stringMatcher)) 
} 

Cách sử dụng:

onView(withTextInputHint(R.string.hint)).perform(ViewActions.typeText("Type text here"))

Các vấn đề liên quan