Android
Espresso
ファイルを選択して、その名称を表示するActivityのテストです。
Intent.ACTION_GET_CONTENTを使って、ファイル選択のダイアログを表示し、ファイルを選択して、その名称が表示されているかどうかというテストです。
※ちょっとしょっぱいことに、ファイル選択のダイアログ表示→そのあとファイルを選択する、というところまでは、自動化できませんでした(^_^;
この記事と
https://codelabs.developers.google.com/codelabs/android-testing/index.html?index=..%2F..%2Findex&hl=ja#7
こちらのStack Overflowを参考に
http://stackoverflow.com/questions/32142463/how-to-stub-select-images-intent-using-espresso-intents
作成しています。
@RunWith(AndroidJUnit4.class)
@LargeTest
public class AddFileToRegisterTest {
public static final String FACE_PHOTO_PATH = "/storage/emulated/0/Download/スクリーンショット-2015-07-16-23.37.54.png";
public static final String FACE_PHOTO_NAME = "スクリーンショット-2015-07-16-23.37.54.png";
@Rule
public IntentsTestRule<RegisterActivity> mRegisterIntentsTestRule =
new IntentsTestRule<>(RegisterActivity.class);
@Before
public void registerIdlingResource() {
Espresso.registerIdlingResources(
mRegisterIntentsTestRule.getActivity().getCountingIdlingResource());
}
@Test
public void activityResult_IsHandledProperly() {
// Build a result to return when a particular activity is launched.
Bundle bundle = new Bundle();
ArrayList<Parcelable> parcels = new ArrayList<>();
Intent resultData = new Intent();
Uri uri1 = Uri.parse("file:/" + FACE_PHOTO_PATH);
Parcelable parcelable1 = (Parcelable) uri1;
parcels.add(parcelable1);
bundle.putParcelableArrayList(Intent.EXTRA_STREAM, parcels);
// Create the Intent that will include the bundle.
resultData.putExtras(bundle);
Instrumentation.ActivityResult result = createImageCaptureActivityResultStub();
intending(allOf(
hasAction(equalTo(Intent.ACTION_GET_CONTENT))
)).respondWith(result);
// User action that results in "contacts" activity being launched.
// Launching activity expects phoneNumber to be returned and displays it on the screen.
onView(withId(R.id.last_name)).perform(closeSoftKeyboard());
onView(withId(R.id.face_photo_upload)).perform(scrollTo()).perform(click());
onView(withId(R.id.face_photo_title))
.perform(scrollTo()) // Scroll to thumbnail
.check(matches(withText(FACE_PHOTO_NAME)));
}
/**
* Unregister your Idling Resource so it can be garbage collected and does not leak any memory.
*/
@After
public void unregisterIdlingResource() {
Espresso.unregisterIdlingResources(
mRegisterIntentsTestRule.getActivity().getCountingIdlingResource());
}
private Instrumentation.ActivityResult createImageCaptureActivityResultStub() {
// Create the ActivityResult, with a null Intent since we do not want to return any data
// back to the Activity.
return new Instrumentation.ActivityResult(Activity.RESULT_OK, null);
}
}
ハマったことは
intending(allOf(
hasAction(equalTo(Intent.ACTION_GET_CONTENT))
)).respondWith(result);
が、どうしても中身がNullになって、ヌルポで落ちてしまうことです。
答えは、Espressoさんの公式サイトに書いてありました!
Espresso-Intentsを利用するときは、IntentsTestRulを使えということだそうです。
いつものことですけどね、ちゃんとドキュメントは読むように!ってことですね。。。
IntentsTestRule
Use IntentsTestRule instead of ActivityTestRule when using Espresso-Intents. IntentsTestRule makes it easy to use Espresso-Intents APIs in functional UI tests. This class is an extension of ActivityTestRule, which initializes Espresso-Intents before each test annotated with @Test and releases Espresso-Intents after each test run. The activity will be terminated after each test and this rule can be used in the same way as ActivityTestRule.
@Rule
public IntentsTestRule<RegisterActivity> mRegisterIntentsTestRule =
new IntentsTestRule<>(RegisterActivity.class);