如何使用Android Espresso测试TextInputLayout值(提示、错误等)?
如果我的如何使用Android Espresso测试TextInputLayout值(提示、错误等)?,android,android-layout,android-espresso,Android,Android Layout,Android Espresso,如果我的TextInputLayout视图有特定提示,我将尝试使用Espresso进行测试。我使用的代码如下: Espresso.onView(ViewMatchers.withId(R.id.edit_text_email)) .check(ViewAssertions.matches( ViewMatchers.withHint(R.string.edit_text_email_hint))) 这适用于正常的EditText视图,而不是包装在TextInputLay
TextInputLayout
视图有特定提示,我将尝试使用Espresso进行测试。我使用的代码如下:
Espresso.onView(ViewMatchers.withId(R.id.edit_text_email))
.check(ViewAssertions.matches(
ViewMatchers.withHint(R.string.edit_text_email_hint)))
这适用于正常的EditText
视图,而不是包装在TextInputLayout
中。然而,当它环绕时,它就不再工作了
我试图使用来自的解决方案,但仍然不起作用
我还调查了:报告了这个问题,它说通过使用提示指向当前的代码,解决方法非常简单,但我无法让它工作
有什么办法解决这个问题吗?这是我的自定义匹配器:
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) {
}
};
}
}
与
希望它能帮助更通用的解决方案,该解决方案适用于任何具有“getHint”方法的视图:
上述解决方案不适用于我的用例。我想找到文本InputItemText并在其中键入文本。以下是我的解决方案:
@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))
}
@VisibleForTesting
使用TextInputLayoutAuthIntMatcher@RemoteMsgConstructor初始化
构造函数(@field:RemoteMsgField(order=0)
private val stringMatcher:Matcher):TypeSafeMatcher(){
覆盖乐趣描述(描述:描述){
description.appendText(“带有TextInputLayout提示:”)
stringMatcher.Descripto(描述)
}
public override fun matchessesafely(textinputtext:View):布尔值{
如果(textInputItemText!是textInputItemText)返回false
返回stringMatcher.matches((textInputItemText.parent.parent作为?TextInputLayout)?.hint)
}
}
/**
*返回一个匹配器,该匹配器根据[TextInputItemText]的提示属性值匹配[TextInputItemText]。
*
*
***注意:**视图中的sugar表示`withHint(is(“string”)`)。
*
*@param hintText[String]与要匹配的提示文本
*/
有趣的文本输入(hintText:String):匹配器{
返回时使用textinputhint(Matchers.`is`(checkNotNull(hintText)))
}
/**
*返回一个匹配器,该匹配器匹配显示提示的[TextInputInputText]的子代
*与给定的资源id关联。
*
*@param resourceId文本视图应具有的字符串资源作为提示。
*/
textinputhint(resourceId:Int)的乐趣:匹配器{
返回时使用TextInput(getString(resourceId))
}
/**
*返回基于提示属性值与[TextView]匹配的匹配器。
*
*
***注意:**视图的提示属性可以为'null',以便与之匹配`
*withHint(空值(String.class)`
*
*@param stringMatcher[`Matcher
`](http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matcher.html)*包含要匹配的文本的[字符串]
*/
文本输入权限的乐趣(stringMatcher:Matcher):Matcher{
使用TextInputLayoutAuthIntMatcher(checkNotNull(stringMatcher))返回
}
用法:
onView(withId(R.id.SomeLayout)).check(matches(withCustomHint(is("SomeString"))));
onView(withTextInputHint(R.string.hint))。执行(ViewActions.typeText(“此处键入文本”))
更简单的解决方案是检查错误文本是否可见,例如:
val text = mTestRule.getActivity().getString(R.string.error_text)
onView(withText(text)).check(matches(isDisplayed()))
piotrek1543答案的Kotlin版本:
fun hasTextInputLayoutHintText(expectedErrorText: String): Matcher<View> = object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description?) { }
override fun matchesSafely(item: View?): Boolean {
if (item !is TextInputLayout) return false
val error = item.hint ?: return false
val hint = error.toString()
return expectedErrorText == hint
}
}
fun HastextInputLayoutIntText(expectedErrorText:String):Matcher=object:TypeSafeMatcher(){
重写fun Descripto(描述:描述?{}
覆盖趣味匹配安全(项目:视图?):布尔值{
如果(item!为TextInputLayout)返回false
val error=item.hint?:返回false
val hint=error.toString()
返回expectedErrorText==提示
}
}
如果要检查材质TextInputLayout中的错误,请尝试以下操作:
onView(withId(R.id.exampleView)).check(matches(withHint("example text")))
onView(带id(viewId)).check(匹配(textInputLayoutErrorTextMatcher(getString(stringId)))
确保提供TextInputLayout的id,而不是其子项(即TextInputItemText)。可以避免Java反射。此外,TextView及其所有子体(包括TextInputItemText)或TextInputLayout都支持提示。因此
fun withHint(expected: String) = object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("TextView or TextInputLayout with hint '$expected'")
}
override fun matchesSafely(item: View?) =
item is TextInputLayout && expected == item.hint || item is TextView && expected == item.hint
}
你有两个解决方案
-首先
onView(withText(errorMessage)).check(matches(isDisplayed()))
-第二
onView(withId(R.id.textinput_error)).check(matches(withText(errorMessage)))
有些adobe解决方案是正确的,但我想添加一个kotlin版本,我认为它比其他版本更简单:
fun hasNoErrorText() = object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("has no error text ")
}
override fun matchesSafely(view: View?) = view is TextInputLayout && view.error == null
}
fun hasnorerrortext()=对象:TypeSafeMatcher(){
覆盖乐趣描述(描述:描述){
description.appendText(“没有错误文本”)
}
override fun matchesSafely(视图:视图?)=视图为TextInputLayout&&view.error==null
}
使用BoundedMatcher
可以取消类型检查:
fun withHint(@StringRes hintId: Int?) =
object : BoundedMatcher<View, TextInputLayout>(TextInputLayout::class.java) {
override fun matchesSafely(item: TextInputLayout?): Boolean =
when {
item == null -> false
hintId == null -> item.hint == null
else -> item.hint?.toString() == item.context.getString(hintId)
}
override fun describeTo(description: Description?) {
description?.appendText("with hint id $hintId")
}
}
funwithhint(@StringRes-hintId:Int?)=
对象:BoundedMatcher(TextInputLayout::class.java){
覆盖有趣的匹配消息(项目:TextInputLayout?):布尔值=
什么时候{
项==null->false
hintId==null->item.hint==null
else->item.hint?.toString()==item.context.getString(hintId)
}
覆盖乐趣描述(描述:描述?){
说明?.appendText(“带有提示id$hintId”)
}
}
我可以将自定义匹配器HastextInputLayoutIntText放在哪里?因为在我的代码中我将错误设置为TextInputItemText,所以我必须在匹配器中将TextInputLayout更改为TextInputItemText。如果您继承自
onView(withText(errorMessage)).check(matches(isDisplayed()))
onView(withId(R.id.textinput_error)).check(matches(withText(errorMessage)))
fun hasNoErrorText() = object : TypeSafeMatcher<View>() {
override fun describeTo(description: Description) {
description.appendText("has no error text ")
}
override fun matchesSafely(view: View?) = view is TextInputLayout && view.error == null
}
fun withHint(@StringRes hintId: Int?) =
object : BoundedMatcher<View, TextInputLayout>(TextInputLayout::class.java) {
override fun matchesSafely(item: TextInputLayout?): Boolean =
when {
item == null -> false
hintId == null -> item.hint == null
else -> item.hint?.toString() == item.context.getString(hintId)
}
override fun describeTo(description: Description?) {
description?.appendText("with hint id $hintId")
}
}