使用Espresso来测试可绘制的变化

我是新来Espresso测试,但似乎没有任何方法来测试可绘制的更改。

我有一个教程是一个ImageView Drawable幻灯片’塞进’一个半透明的TextView 。 在我的测试中,我想确保按下下一个按钮时,正确的Drawable已经插入教程的ImageView

没有默认的Matcher来检查Drawable ,所以我开始使用https://stackoverflow.com/a/28785178/981242写我自己的。 不幸的是,由于无法检索ImageView的活动Drawable的id,所以无法完成matchesSafely()实现。

这不是测试活动Drawable的唯一用例。 人们通常使用的工具是什么?

我不喜欢比较位图,而是按照这个答案的建议: https : //stackoverflow.com/a/14474954/1396068

当设置图像视图的drawable时,还可以用setTag(R.drawable.your_drawable)将可绘制的ID存储在它的标签中。 然后使用Espresso的withTag(equalTo(R.drawable.your_drawable))匹配器来检查正确的标签。

请检查我发现的这个教程。 似乎工作相当不错https://medium.com/@dbottillo/android-ui-test-espresso-matcher-for-imageview-1a28c832626f#.4snjg8frw

这是复制意大利面的摘要;-)

 public class DrawableMatcher extends TypeSafeMatcher { private final int expectedId; String resourceName; public DrawableMatcher(int expectedId) { super(View.class); this.expectedId = expectedId; } @Override protected boolean matchesSafely(View target) { if (!(target instanceof ImageView)){ return false; } ImageView imageView = (ImageView) target; if (expectedId < 0){ return imageView.getDrawable() == null; } Resources resources = target.getContext().getResources(); Drawable expectedDrawable = resources.getDrawable(expectedId); resourceName = resources.getResourceEntryName(expectedId); if (expectedDrawable == null) { return false; } Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); Bitmap otherBitmap = ((BitmapDrawable) expectedDrawable).getBitmap(); return bitmap.sameAs(otherBitmap); } @Override public void describeTo(Description description) { description.appendText("with drawable from resource id: "); description.appendValue(expectedId); if (resourceName != null) { description.appendText("["); description.appendText(resourceName); description.appendText("]"); } } } 

请注意,这只有当您的Drawable是一个BitmapDrawable 。 如果你也有VectorDrawable或其他Drawable你必须检查这个( imageView.getDrawable() instanceOf XXXDrawable ),并从中获取位图。 除了你有一些简单的Drawable,你只需要一种颜色,你就可以比较。

例如,要获得VectorDrawable的位图,必须将VectorDrawable绘制到canvas上,并将其保存为位图(VectorDrawable着色时我遇到了一些麻烦)。 如果你有一个StateListDrawable,你可以得到所选状态的Drawable,并重复你的if instanceOf级联。 对于其他Drawabletypes,我没有任何经验,对不起!

有一个与Frankie Sardo的 withImageDrawable()withImageDrawable()withImageDrawable()匹配器相关的要点。 所有学分给他。

而对于图像id – 你可以输入R.drawable.image_name ,那么drawable的id将被自动检索。

基于@wolle和@FreewheelNat的帮助,用于比较(Vector)Drawable:

 public static Matcher withDrawableId(@DrawableRes final int id) { return new DrawableMatcher(id); } public static class DrawableMatcher extends TypeSafeMatcher { private final int expectedId; private String resourceName; public DrawableMatcher(@DrawableRes int expectedId) { super(View.class); this.expectedId = expectedId; } @Override protected boolean matchesSafely(View target) { if (!(target instanceof ImageView)) { return false; } ImageView imageView = (ImageView) target; if (expectedId < 0) { return imageView.getDrawable() == null; } Resources resources = target.getContext().getResources(); Drawable expectedDrawable = resources.getDrawable(expectedId); resourceName = resources.getResourceEntryName(expectedId); if (expectedDrawable != null && expectedDrawable.getConstantState() != null) { return expectedDrawable.getConstantState().equals( imageView.getDrawable().getConstantState() ); } else { return false; } } @Override public void describeTo(Description description) { description.appendText("with drawable from resource id: "); description.appendValue(expectedId); if (resourceName != null) { description.appendText("["); description.appendText(resourceName); description.appendText("]"); } } } 

我接受@wolle的答案是有效的,但是我想承认,即使对于Java,它也可能比这更简单 。 它可以被转换成一个static function (或Kotlin中的一个companion ),也可以清除一些不推荐使用的代码

无论如何,Kotlin的代码压缩 – 不推荐使用的解决方案是:

  fun drawableIsCorrect(@DrawableRes drawableResId: Int): Matcher { return object : TypeSafeMatcher() { override fun describeTo(description: Description) { description.appendText("with drawable from resource id: ") description.appendValue(drawableResId) } override fun matchesSafely(target: View?): Boolean { if (target !is ImageView) { return false } if (drawableResId < 0) { return target.drawable == null } val expectedDrawable = ContextCompat.getDrawable(target.context, drawableResId) ?: return false val bitmap = (target.drawable as BitmapDrawable).bitmap val otherBitmap = (expectedDrawable as BitmapDrawable).bitmap return bitmap.sameAs(otherBitmap) } } } 

22线vs 44,呃?