Progressbars and Espresso

Assert progress of ProgressBar in Espresso test

It would seem Espresso does not allow to check the progress attribute using a ViewInteraction. Although, it is possible to recover the progress bar view directly from the view and to assert its value using assertThat.

@Test
public void ExampleAssertProgressBar(){
ProgressBar progressBar = activity.getActivity().findViewById(R.id.progressBar);
int progress = progressBar.getProgress();
assertThat(progress, equalTo(50));
}

Since this is pretty straightforward, I assume it is the way to go.

Testing progress bar on Android with Espresso

Espresso has problems with the animation. You can just set the drawable of the progress bar to something static just for the test and it works as expected.

Drawable notAnimatedDrawable = ContextCompat.getDrawable(getActivity(), R.drawable.whatever);
((ProgressBar) getActivity().findViewById(R.id.progress_bar)).setIndeterminateDrawable(notAnimatedDrawable);

onView(withId(R.id.progress_bar)).check(matches(isDisplayed()));

any method to wait until invisible progressbar in espresso test?

So, you want to wait until your ProgressBar is hidden.
You can either create an idling resource or use a custom ViewAction as this one:

/**
* Perform action of waiting until the element is accessible & not shown.
* @param viewId The id of the view to wait for.
* @param millis The timeout of until when to wait for.
*/
public static ViewAction waitUntilNotShown(final int viewId, final long millis) {
return new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isRoot();
}

@Override
public String getDescription() {
return "wait for a specific view with id <" + viewId + "> is hidden during " + millis + " millis.";
}

@Override
public void perform(final UiController uiController, final View view) {
uiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
final Matcher<View> viewMatcher = withId(viewId);

do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {
// found view with required ID
if (viewMatcher.matches(child) && !child.isShown()) {
return;
}
}

uiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);

// timeout happens
throw new PerformException.Builder()
.withActionDescription(this.getDescription())
.withViewDescription(HumanReadables.describe(view))
.withCause(new TimeoutException())
.build();
}
};
}

And you can use it this way:

onView(isRoot()).perform(waitUntilNotShown(R.id.theIdToWaitFor, 5000));

changing theIdToWaitFor with the specific id of your ProgressBar and updating the timeout of 5 secs (5000 millis) if necessary.

However, depending on which test you are doing, if this is not an integration test it's better not to make real api calls.

Test loader displayed before data with Espresso

You must disable the loader animations or espresso will wait for them to finish before continuing with the test.

You can replace the progressbar views with plain views for testing:
https://blog.entwicklerbier.org/2015/05/test-your-ui-on-android-with-espresso-damn-you-progressbar/

Or you can change the progressbar drawable:

ProgressBars and Espresso
Or
Testing progress bar on Android with Espresso

And maybe you should also delay the load as you said.



Related Topics



Leave a reply



Submit