用 Espresso 检查 TextView 的 CompundDrawable

Posted

技术标签:

【中文标题】用 Espresso 检查 TextView 的 CompundDrawable【英文标题】:Check CompundDrawable of TextView with Espresso 【发布时间】:2020-05-08 10:04:53 【问题描述】:

我是 Espresso 测试和 android 的新手。我正在尝试测试文本旁边是否显示了正确的图标。 图标设置为:

public void setLabelTextIcon(@DrawableRes int iconResId) 
    txtLabel.setCompoundDrawablesRelativeWithIntrinsicBounds(iconResId, 0,0,0);

我在网上找到了这个https://gist.github.com/frankiesardo/7490059,但它对我不起作用。由于我缺乏背景知识,我无法更改它工作的代码。 目前我正在尝试

    onView(withId(R.id.blue_triple_stripe_txtLabel)).check(matches(withActionIconDrawable(R.drawable.ic_date_grey)));

withActionIconDrawable() 是

public static Matcher<View> withActionIconDrawable(@DrawableRes final int resourceId) 
    return new BoundedMatcher<View, ActionMenuItemView>(ActionMenuItemView.class) 
        @Override
        public void describeTo(final Description description) 
            description.appendText("has image drawable resource " + resourceId);
        

        @Override
        public boolean matchesSafely(final ActionMenuItemView actionMenuItemView) 
            return sameBitmap(actionMenuItemView.getContext(), actionMenuItemView.getItemData().getIcon(), resourceId);
        
    ;

我得到的错误是

androidx.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'has image drawable resource 2131230871' doesn't match the selected view.
Expected: has image drawable resource 2131230871
Got: "AppCompatTextViewid=2131296335, res-name=blue_triple_stripe_txtLabel, visibility=VISIBLE, width=342, height=72, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, layout-params=androidx.constraintlayout.widget.ConstraintLayout$LayoutParams@4d24b35, tag=null, root-is-layout-requested=false, has-input-connection=false, x=206.0, y=18.0, text=2019-04-12, input-type=0, ime-target=false, has-links=false"

谢谢!

【问题讨论】:

【参考方案1】:

这在 Kotlin 中适用于我

fun withDrawableTextView(@DrawableRes id: Int) = object : TypeSafeMatcher<View>() 
   override fun describeTo(description: Description) 
       description.appendText("ImageView with drawable same as drawable with id $id")
    

   override fun matchesSafely(tv: View?): Boolean 
       if (tv is TextView) 
           if (tv.requestFocusFromTouch()) 
               for (d in tv.compoundDrawables) 
                   if (d != null) 
                      val context = tv.context
                      if (sameBitmap(tv.getContext(), d, id)) 
                          return true
                      
                   
       
      return false
     

声明sameBitmap与此处相同:

private fun sameBitmap(context: Context, drawable: Drawable, resourceId: Int): Boolean 
   var drawable: Drawable? = drawable
   var otherDrawable: Drawable = context.getResources().getDrawable(resourceId)
   if (drawable == null || otherDrawable == null) 
      return false
   
   if (drawable is StateListDrawable && otherDrawable is StateListDrawable) 
      drawable = drawable.current
      otherDrawable = otherDrawable.current
   
   if (drawable is BitmapDrawable) 
      val bitmap: Bitmap = (drawable as BitmapDrawable).getBitmap()
      val otherBitmap: Bitmap = (otherDrawable as BitmapDrawable).getBitmap()
      return bitmap.sameAs(otherBitmap)
  
  return false

将其与以下代码一起使用:

  onView(withId(R.id.edit_txt_password)).check(matches(withDrawableTextView(R.drawable.view_password_xxxdp)))

【讨论】:

以上是关于用 Espresso 检查 TextView 的 CompundDrawable的主要内容,如果未能解决你的问题,请参考以下文章

Espresso - 使用异步加载的数据断言 TextView

如何在Espresso中做一个测试,检查包含HTML标签的字符串?

检查 Espresso 是不是显示对话框

Android 自动化测试 Espresso篇:异步代码测试

如何在 espresso UI 测试中检查动态文本

Android用复选框onClick刷新TextView?