// Start the main activity of the application under test mActivity = getActivity(); // Get a handle to the Activity object's main UI widget, a Spinner mSpinner = (Spinner) mActivity.findViewById(com.android.example.spinner.R.id.Spinner); // Set the Spinner to a known position mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); // Stop the activity - The onDestroy() method should save the state of the Spinner mActivity.finish(); // Re-start the Activity - the onResume() method should restore the state of the Spinner mActivity = getActivity(); // Get the Spinner's current position int currentPosition = mActivity.getSpinnerPosition(); // Assert that the current position is the same as the starting position assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); Test Activity state saving and restoration
Google Android Testing Codelab Best (introductory) Android testing example available at the moment (imho) https://www.code-labs.io/codelabs/android-testing/
Espresso test anatomy @RunWith(AndroidJUnit4.class) @LargeTest public class NotesScreenTest { @Rule public ActivityTestRule notesActivityTestRule = new ActivityTestRule<>(NotesActivity.class);
Espresso test anatomy @RunWith(AndroidJUnit4.class) @LargeTest public class NotesScreenTest { @Rule public ActivityTestRule notesActivityTestRule = new ActivityTestRule<>(NotesActivity.class);
Espresso: exercise UI @Test public void addNoteToNotesList() throws Exception {
// Click on the add note button onView(withId(R.id.fab_add_notes)).perform(click());
// Add note title and description onView(withId(R.id.add_note_title)).perform(typeText(“More”)); onView(withId(R.id.add_note_description)).perform(typeText(“Testing”));
// Save the note onView(withId(R.id.fab_add_notes)).perform(click());
// Verify note is displayed on screen onView(withItemText(“Testing”)).check(matches(isDisplayed())); }
Espresso: exercise UI @Test public void addNoteToNotesList() throws Exception {
// Click on the add note button onView(withId(R.id.fab_add_notes)).perform(click());
// Add note title and description onView(withId(R.id.add_note_title)).perform(typeText(“More”)); onView(withId(R.id.add_note_description)).perform(typeText(“Testing”));
// Save the note onView(withId(R.id.fab_add_notes)).perform(click());
// Verify note is displayed on screen onView(withItemText(“Testing”)).check(matches(isDisplayed())); }
Espresso: exercise UI @Test public void addNoteToNotesList() throws Exception {
// Click on the add note button onView(withId(R.id.fab_add_notes)).perform(click());
// Add note title and description onView(withId(R.id.add_note_title)).perform(typeText(“More”)); onView(withId(R.id.add_note_description)).perform(typeText(“Testing”));
// Save the note onView(withId(R.id.fab_add_notes)).perform(click());
// Verify note is displayed on screen onView(withItemText(“Testing”)).check(matches(isDisplayed())); }
Intent validation @Test public void validateIntentSentToPackage() { // User action that results in an external "phone" activity being launched. user.clickOnView(system.getView(R.id.callButton)); // Using a canned RecordedIntentMatcher to validate that an intent resolving // to the "phone" activity has been sent. intended(toPackage("com.android.phone")); }
Intent stubbing @Test public void activityResult_IsHandledProperly() { // Build a result to return when a particular activity is launched. Intent resultData = new Intent(); String phoneNumber = "012-345-678"; resultData.putExtra("phone", phoneNumber); ActivityResult result = new ActivityResult(Activity.RESULT_OK, resultData); // Set up result stubbing when an intent sent to "contacts" is seen. intending(toPackage("com.android.contacts")).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.pickButton)).perform(click()); // Assert that data we set up above is shown. onView(withId(R.id.phoneNumber).check(matches(withText(phoneNumber))); }
Espresso synchronization public class IdleMonitor implements IdlingResource {
@Override public String getName() { return IdleMonitor.class.getSimpleName(); }
@Override public boolean isIdleNow() { // return true if resource is idle return false; }
@Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { // store a reference to the resourceCallback // notify resourceCallback when idle } } Espresso.registerIdlingResources(idlingResource);
Suggested reading Test Driven Development: By Example Beck, Kent (978-0321146533) Continuous Integration: Improving Software Quality and Reducing Risk Duvall, Paul M. et al. (978-0321336385) Working Effectively with Legacy Code Feathers, Michael (978-0131177055)