The best and right way is to use Espresso Intents. So you need to add a dependency to your build.gradle application
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
In my case, I opened the gallery using a button in my application, then the code for the test and adding the target and intended Espresso APIs as follows:
@Test fun photos_CreationGalleryClickUI() { savePickedImage() val imgGalleryResult = createImageGallerySetResultStub() intending(hasAction(Intent.ACTION_CHOOSER)).respondWith(imgGalleryResult) onView(withId(R.id.photos_button_gallery)).perform(click()) onView(withId(R.id.photos_bigimage_viewer)).check(matches(hasImageSet())) }
Here, matching for indexing is the key when the gallery should be open and avoid manually selecting an image:
hasAction(Intent.ACTION_CHOOSER)
I use two helpers: savePickedImage () to simulate an image from the gallery
private fun savePickedImage() { val bm = BitmapFactory.decodeResource(mActivityTestRule.activity.resources, R.mipmap.ic_launcher) assertTrue(bm != null) val dir = mActivityTestRule.activity.externalCacheDir val file = File(dir?.path, "myImageResult.jpeg") System.out.println(file.absolutePath) val outStream: FileOutputStream? try { outStream = FileOutputStream(file) bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream) outStream.flush() outStream.close() } catch (e: FileNotFoundException) { e.printStackTrace() } catch (e: IOException) { e.printStackTrace() } }
And createImageGallerySetResultStub to stub the result after the "select" image. Here it would be important to put the result in the form of an array of packages, without it the result would never be recognized:
private fun createImageGallerySetResultStub(): Instrumentation.ActivityResult { val bundle = Bundle() val parcels = ArrayList<Parcelable>() val resultData = Intent() val dir = mActivityTestRule.activity.externalCacheDir val file = File(dir?.path, "myImageResult.jpeg") val uri = Uri.fromFile(file) val myParcelable = uri as Parcelable parcels.add(myParcelable) bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels) resultData.putExtras(bundle) return Instrumentation.ActivityResult(Activity.RESULT_OK, resultData) }
hasImageSet () as a match helper that checks if imageView has or not:
return item.getDrawable() == null
NOTE. Remember to set the grant rule to avoid permission problems and define the test rule as an IntentTestRule (which is already expanding from ActivityTestRule)
@get:Rule var mActivityTestRule = IntentsTestRule(AuctionCreationActivity::class.java)
@get: Rule var mRuntimePermissionRule = GrantPermissionRule.grant (android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
Dependence:
androidTestImplementation "androidx.test:rules:$testRules"