I'm new to Espresso testing, but there doesn't seem like there's any way to test drawable changes.
I have a tutorial that is an ImageView
Drawable
slideshow 'tucked into' a semi-transparent TextView
. In my tests, I want to ensure that when the next button is pressed, the proper Drawable
has been inserted into the tutorial's ImageView
.
There is no default Matcher
to check for Drawable
s, so I set out to write my own using https://stackoverflow.com/a/28785178/981242. Unfortunately, since there is no way to retrieve the id of an ImageView
's active Drawable
, I can't complete the matchesSafely()
implementation.
This can't be the only use case for testing active Drawable
s. What is the tool that people normally use for situations like this?
I accept the answer of @wolle as valid, but I would like to admit that, even for Java, it could be even simpler than that. It can be converted into a
static function
(or acompanion
in Kotlin) and also clean some deprecated code.Anyway, the code-compacted-non-deprecated solution for Kotlin would be this:
22 lines vs 44, eh?
I already answered on the similar topic here: Get the ID of a drawable in ImageView. The approach is based on tagging a view with a specified resource id in the custom
LayoutInflater
. Whole process is automated by a simple library TagView. It's especially handy for Espresso test because you don't need to tag every view in your project manually. In fact, you don't need to change anything, except you set some drawables in runtime. In that case you need to look into Tagging in runtime section.As a result, you can compare two drawables just by their ids:
Custom Espresso assertion
assertTagKeyValue
is available hereThere is one gist which contains
withBackground()
,withCompoundDrawable()
,withImageDrawable()
matchers from Frankie Sardo. All credits to him.And regarding image ids - you can type
R.drawable.image_name
, then the id of the drawable will be retrieved automatically.Based on @wolle and @FreewheelNat's help, for comparing (Vector) Drawable:
I prefer not to compare bitmaps and instead follow this answer's advice: https://stackoverflow.com/a/14474954/1396068
When setting the image view's drawable, also store the drawable ID in its tag with
setTag(R.drawable.your_drawable)
. Then use Espresso'swithTagValue(equalTo(R.drawable.your_drawable))
matchers to check for the correct tag.please check this tutorial I found. Seems to work pretty good https://medium.com/@dbottillo/android-ui-test-espresso-matcher-for-imageview-1a28c832626f#.4snjg8frw
Here is the summary for copy pasta ;-)
Please be aware that this only works when your
Drawable
is aBitmapDrawable
. If you also haveVectorDrawable
or otherDrawable
you have to check for this (imageView.getDrawable() instanceOf XXXDrawable
) and get the bitmap out of it. Except you have some kind of simple Drawable where you just have one color or so you can compare.To get the Bitmap of a VectorDrawable for example you have to draw the VectorDrawable to a canvas and save it to a bitmap (I had some trouble when the VectorDrawable was tinted). If you have a StateListDrawable you can get the Drawable of the selected state and repeat your if instanceOf cascade. For other Drawable types I don't have any experience, sorry!