Insider's Guide To Udacity Android Developer Nanodegree Part 3 - Making the Baking App |
Written by Nikos Vaggalis |
Monday, 03 July 2017 |
Page 7 of 8
Step 6 - UI testing with Espresso
Google offers a nice cheatsheet of the Espresso utility methods.
After some digging, the solution was to exclude: androidTestCompile ( 'com.android.support.test.espresso:espresso-contrib:2.2.2'){
exclude group: 'com.android.support', module: 'appcompat-v7'
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'recyclerview-v7' }
Anyway, wanting to test my RecipeActivity, I wrapped it up into an Espresso public ActivityTestRule<RecipeActivity> mActivityTestRule = new ActivityTestRule<>(RecipeActivity.class);
@Test public void checkText_RecipeActivity() { onView(ViewMatchers.withId(R.id.recipe_recycler))
.perform(RecyclerViewActions.scrollToPosition(1));
onView(withText("Brownies")).check(matches(isDisplayed())); } @Test public void checkPlayerViewIsVisible_RecipeDetailActivity1() { onView(ViewMatchers.withId(R.id.recipe_recycler)) .perform(RecyclerViewActions
.actionOnItemAtPosition(0,click()));
onView(ViewMatchers.withId(R.id.recipe_detail_recycler)) .perform(RecyclerViewActions
.actionOnItemAtPosition(0,click()));
onView(withId(R.id.playerView)) .check(matches(isDisplayed()));
}
onView(withId(R.id.playerView)).check(matches(isDisplayed()));
However, because the list of the recipes is loaded asynchronously due to Retrofit's @Before public void registerIdlingResource() { mIdlingResource = mActivityTestRule.getActivity() .getIdlingResource();
// To prove that the test fails, omit this call: Espresso.registerIdlingResources(mIdlingResource); } @Test public void checkText_RecipeActivity() { onView(ViewMatchers.withId(R.id.recipe_recycler)) .perform(RecyclerViewActions.scrollToPosition(1));
onView(withText("Brownies")).check(matches(isDisplayed()));
} @Test public void checkPlayerViewIsVisible_RecipeDetailActivity1() { onView(ViewMatchers.withId(R.id.recipe_recycler)) .perform(RecyclerViewActions
.actionOnItemAtPosition(0,click()));
onView(ViewMatchers.withId(R.id.recipe_detail_recycler)) .perform(RecyclerViewActions
.actionOnItemAtPosition(0,click()));
onView(withId(R.id.playerView)).check(matches(isDisplayed())); }
@After public void unregisterIdlingResource() { if (mIdlingResource != null) { Espresso.unregisterIdlingResources(mIdlingResource); } }
The IdlingResource initialization should happen inside the activity in question: @VisibleForTesting @NonNull public IdlingResource getIdlingResource() { if (mIdlingResource == null) { mIdlingResource = new SimpleIdlingResource(); } return mIdlingResource; }
and it is this instance handed over to the fragment that does the async work, that is RecipeFragment
SimpleIdlingResource idlingResource = (SimpleIdlingResource)((RecipeActivity)getActivity())
.getIdlingResource();
uses it to make the actual network call when the activity is idle, that is all UI code has been run to completion
recipe.enqueue(new Callback<ArrayList<Recipe>>() { @Override public void onResponse(Call<ArrayList<Recipe>> call, Response<ArrayList<Recipe>> response) {
Integer statusCode = response.code(); Log.v("status code: ", statusCode.toString()); ArrayList<Recipe> recipes = response.body(); Bundle recipesBundle = new Bundle(); recipesBundle.putParcelableArrayList( ALL_RECIPES, recipes);
recipesAdapter.setRecipeData(recipes,getContext()); if (idlingResource != null) { idlingResource.setIdleState(true); } } @Override public void onFailure(Call<ArrayList<Recipe>> call, Throwable t) {
Log.v("http fail: ", t.getMessage()); } });
|
Last Updated ( Monday, 20 November 2017 ) |