Android system uses intent for communication. Intent can contain information (component, action, category, data, extras and more). We can send the intent to other application and can get it from other application too.
In this blog we will create the simple application can take a photo and show photo in the image view.
When click on “Take a Photo
” button, it will send intent to launch camera application. Then when photo was taken, the bitmap photo result will return back to onActivityResult
method.
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bundle extras = data.getExtras(); if (extras == null || !extras.containsKey("data")) { return; } Bitmap imageBitmap = (Bitmap) extras.get("data"); mImageView.setImageBitmap(imageBitmap); } }
Setup
defaultConfig { ... testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } dependencies { ... androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2' androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2' }
Write the Test
Create activity test class and add runner annotation.
@RunWith(AndroidJUnit4.class) public class TakePhotoActivityTest { }
Add intent test rule.
@Rule public IntentsTestRule mIntentsRule = new IntentsTestRule<>(TakePhotoActivityTest.class);
First test, when click on “Take a Photo
” button, it will open camera application.
@Test public void takePhoto_shouldOpenCamera() { onView(withId(R.id.btn_take_photo)).perform(click()); intended(hasAction(equalTo(MediaStore.ACTION_IMAGE_CAPTURE))); }
Camera app launched by receiving intent that contain ACTION_IMAGE_CAPTURE
, so we will test the camera app receive ACTION_IMAGE_CAPTURE
or not by using intended.
The Second test, that image view will show the image, when taken a photo.
Stub the bitmap image result.
private ActivityResult createImageCaptureActivityResultStub() { // Put the drawable in a bundle. Bundle bundle = new Bundle(); bundle.putParcelable("data", BitmapFactory.decodeResource( activityTestRule.getActivity().getResources(), R.drawable.ic_launcher)); // Create the Intent that will include the bundle. Intent resultData = new Intent(); resultData.putExtras(bundle); // Create the ActivityResult with the Intent. return new ActivityResult(Activity.RESULT_OK, resultData); }
Create custom matcher hasDrawable.
public class ImageViewHasDrawableMatcher { public static BoundedMatcher<View, ImageView> hasDrawable() { return new BoundedMatcher<View, ImageView>(ImageView.class) { @Override protected boolean matchesSafely(ImageView imageView) { return imageView.getDrawable() != null; } @Override public void describeTo(Description description) { description.appendText("has drawable"); } }; } }
Then, use it to check that image view has drawable or not.
@Test public void takePhoto_imageViewHasDrawable() { // check the image view should not has drawable at the first time. onView(withId(R.id.image_view)).check(matches(not(hasDrawable()))); // click on "Take a Photo" button, it will trigger the stubbed intend. onView(withId(R.id.btn_take_photo)).perform(click()); // now the image view should has drawable. onView(withId(R.id.image_view)).check(matches(hasDrawable())); }
Run test!
For more information: Android Testing Support Library