Android 浓缩咖啡。如何检查 TextInputLayout 中的 ErrorText
Android Espresso. How to check ErrorText in TextInputLayout
基本上我正在尝试测试在错误登录后我在电子邮件字段中显示错误。
观点是:
<android.support.design.widget.TextInputLayout
android:id="@+id/ti_email"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingStart="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/authentication_email_placeholder"
android:inputType="textEmailAddress"
android:maxLines="1"
android:textSize="16sp"
tools:text="@string/placeholder_email"/>
</android.support.design.widget.TextInputLayout>
我试着这样做:
onView(withId(R.id.et_email))
.check(matches(hasErrorText(
ctx.getString(R.string.authentication_error_empty_email))));
您可以编写自定义匹配器:
public final class CustomItemMatchers {
private static class TextInputLayoutErrorMatcher extends BoundedMatcher<Object, Wrapper> {
private final Matcher<String> itemTextMatcher;
public TextInputLayoutErrorMatcher(final Matcher<String> itemTextMatcher){
super(TextInputLayout.class);
this.itemTextMatcher = itemTextMatcher;
}
@Override
public void describeTo(Description description) {
description.appendText("with error content: ");
itemTextMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(TextInputLayout til) {
if (til == null) {
return false;
}
return itemTextMatcher.matches((til.getError());
}
}
public static Matcher<Object> withErrorName(final Matcher<String> itemTextMatcher) {
checkNotNull(itemTextMatcher);
return new TextInputLayoutErrorMatcher(itemTextMatcher);
}
}
您可以将它与
一起使用
matches(CustomItemMatchers.withErrorName(equalTo("My Error")))
此代码是用 Espresso 1 编写的,但我希望它仍然有效。
请使用EditText的setError()方法
例如:EditText emailEditText;
if(invalidLogin)
emailEditText.setError("Error Message");
这适用于 CustomMatcher:
public static Matcher<View> hasTextInputLayoutErrorText(final String expectedErrorText) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) view).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
}
};
}
它的工作:)
onView(withId(R.id.et_email)).check(matches(hasErrorText("Error Message")));
写了一个自定义匹配器
import android.view.View;
import com.google.android.material.textfield.TextInputLayout;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class TextInputLayoutErrorMatcher extends TypeSafeMatcher<View>{
private String expectedErrorText;
TextInputLayoutErrorMatcher(String expectedErrorText) {
this.expectedErrorText = expectedErrorText;
}
@Override
protected boolean matchesSafely(View item) {
if (!(item instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) item).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
description.appendText("with error text " + expectedErrorText);
}
}
我认为您希望在 TextInputLayout 而不是 EditText 上设置错误。如果正确,您可以通过以下方式实现。
onView(withId(R.id.ti_email)).check(matches(hasDescendant(
withText(ctx.getString(R.string.authentication_error_empty_email))))
)
如果您不想使用自定义匹配器,在 Kotlin 中您可以通过
获得相同的结果
val expectedString = ctx.getString(R.string.authentication_error_empty_email)
onView(ViewMatchers.withId(R.id.ti_email))
.check { view, _ ->
val actualError = (view as TextInputLayout).error
assertEquals(actualError, expectedError)
}
}
我最喜欢这种方式,因为它可以灵活地处理任何视图
基本上我正在尝试测试在错误登录后我在电子邮件字段中显示错误。
观点是:
<android.support.design.widget.TextInputLayout
android:id="@+id/ti_email"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingStart="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/authentication_email_placeholder"
android:inputType="textEmailAddress"
android:maxLines="1"
android:textSize="16sp"
tools:text="@string/placeholder_email"/>
</android.support.design.widget.TextInputLayout>
我试着这样做:
onView(withId(R.id.et_email))
.check(matches(hasErrorText(
ctx.getString(R.string.authentication_error_empty_email))));
您可以编写自定义匹配器:
public final class CustomItemMatchers {
private static class TextInputLayoutErrorMatcher extends BoundedMatcher<Object, Wrapper> {
private final Matcher<String> itemTextMatcher;
public TextInputLayoutErrorMatcher(final Matcher<String> itemTextMatcher){
super(TextInputLayout.class);
this.itemTextMatcher = itemTextMatcher;
}
@Override
public void describeTo(Description description) {
description.appendText("with error content: ");
itemTextMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(TextInputLayout til) {
if (til == null) {
return false;
}
return itemTextMatcher.matches((til.getError());
}
}
public static Matcher<Object> withErrorName(final Matcher<String> itemTextMatcher) {
checkNotNull(itemTextMatcher);
return new TextInputLayoutErrorMatcher(itemTextMatcher);
}
}
您可以将它与
一起使用matches(CustomItemMatchers.withErrorName(equalTo("My Error")))
此代码是用 Espresso 1 编写的,但我希望它仍然有效。
请使用EditText的setError()方法 例如:EditText emailEditText;
if(invalidLogin)
emailEditText.setError("Error Message");
这适用于 CustomMatcher:
public static Matcher<View> hasTextInputLayoutErrorText(final String expectedErrorText) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(View view) {
if (!(view instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) view).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
}
};
}
它的工作:)
onView(withId(R.id.et_email)).check(matches(hasErrorText("Error Message")));
写了一个自定义匹配器
import android.view.View;
import com.google.android.material.textfield.TextInputLayout;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
public class TextInputLayoutErrorMatcher extends TypeSafeMatcher<View>{
private String expectedErrorText;
TextInputLayoutErrorMatcher(String expectedErrorText) {
this.expectedErrorText = expectedErrorText;
}
@Override
protected boolean matchesSafely(View item) {
if (!(item instanceof TextInputLayout)) {
return false;
}
CharSequence error = ((TextInputLayout) item).getError();
if (error == null) {
return false;
}
String hint = error.toString();
return expectedErrorText.equals(hint);
}
@Override
public void describeTo(Description description) {
description.appendText("with error text " + expectedErrorText);
}
}
我认为您希望在 TextInputLayout 而不是 EditText 上设置错误。如果正确,您可以通过以下方式实现。
onView(withId(R.id.ti_email)).check(matches(hasDescendant(
withText(ctx.getString(R.string.authentication_error_empty_email))))
)
如果您不想使用自定义匹配器,在 Kotlin 中您可以通过
获得相同的结果 val expectedString = ctx.getString(R.string.authentication_error_empty_email)
onView(ViewMatchers.withId(R.id.ti_email))
.check { view, _ ->
val actualError = (view as TextInputLayout).error
assertEquals(actualError, expectedError)
}
}
我最喜欢这种方式,因为它可以灵活地处理任何视图