Tuesday, July 28, 2015

Espresso: Wait for dialog to dismiss

Did you complete the Espresso Idling Resource quiz? Here comes the solution!

DialogFragmentIdlingResource

In the quiz, the test fails because we were verifying the text before the loading dialog dismisses. To make it pass, we can add an idling resource that is only idle when the dialog is not shown.

public DialogFragmentIdlingResource(
    FragmentManager manager, String tag) {
  this.manager = manager;
  this.tag = tag;
}

@Override
public boolean isIdleNow() {
  boolean idle = (manager.findFragmentByTag(tag) == null);
  if (idle) {
    resourceCallback.onTransitionToIdle();
  }
  return idle;
}

The idea is to query the FragmentManager with the tag of the loading dialog. If it is null, the DialogFragment is not there, and we consider the app idle.

Using the idling resource in test

@Test
public void done() {
  IdlingResource idlingResource = new DialogFragmentIdlingResource(
      activityRule.getActivity().getSupportFragmentManager(),
      LoadingDialogFragment.TAG);

  Espresso.registerIdlingResources(idlingResource);

  onView(withId(R.id.text))
      .check(matches(withText(R.string.done)));

  Espresso.unregisterIdlingResources(idlingResource);
}

We create an DialogFragmentIdlingResource with the tag from the loading dialog so that it knows what to wait for. With that, the test will wait until the loading dialog dismisses before proceeding. And now the test passes!

Source code

https://github.com/chiuki/espresso-samples/ under idling-resource-dialog-fragment on the solution branch.

Like this article? Take a look at the outline of my Espresso book and fill in this form to push me to write it! Also check out the published courses: https://gumroad.com/chiuki

Thursday, July 16, 2015

Android Atelier: Lunch In code review

I started an intermediate Android study group with Women Who Code Boulder/Denver called Android Atelier. Our goals are:

  • Explore new techniques
  • Learn from each other
  • Contribute to open source

Hackathon

Our first meetup was on June 9. We brainstormed for our first project, and decided to enter a hackathon together. It was a great way to bootstrap our efforts, using the hackathon to impose a real deadline.

We worked from home after the meetup, keeping in touch on Google Hangout. The time pressure made it a bit stressful, but it was so rewarding to see the group working together and finishing the app in 3 weeks!

Here is our entry, Lunch In:

challengepost.com/software/android-atelier-lunch-in

Code review

We met again on July 14 to review what we did for the app. It was a great discussion of the techniques we used:

  • Fragments
  • BroadcastReceiver to detect wifi state change
  • AlarmManager
  • Notifications
  • Custom view
  • Animations
  • Database (using the Cupboard library)
  • SharedPreferences
  • Testing

I made a screen recording of the code review. Check it out:

Source code: github.com/AndroidAtelier/lunch-in (Tag: v0.1.0)

Tuesday, July 14, 2015

Espresso: Idling Resource quiz

I have written two blog posts on Espresso custom idling resource:

And I am wondering: Is this enough? Do people understand? To figure that out, I made a quiz!

Exercise for the reader

I created a failing test, and your task is to make it pass by adding a custom idling resource. Ready? Here is the code:

https://github.com/chiuki/espresso-samples under idling-resource-dialog-fragment

Fork the repo and commit your answer there. Reply to this Google+ thread with a link to your repo.

The solution will be posted in two weeks.

Solution

Two weeks has passed, so here is the solution!

Like this article? Take a look at the outline of my Espresso book and fill in this form to push me to write it! Also check out the published courses: https://gumroad.com/chiuki

Sunday, July 12, 2015

How to test a watch face?

Fit Cat is an Android Wear watch face that shows the time with a different cat depending on how many steps you walked that day. How do you test something like that? Walk a lot while looking at your watch all the time?

I wrote Fit Cat with a modular structure that allows both unit testing and instrumentation testing.

All Android Wear apps have two modules, mobile and wear. I made them both depend on a ui module, which has the implementation for rendering the bitmap for the watch face. This in turn depends on a lib module, which is a pure Java library.

Unit testing

The lib module contains the pure Java class ActionStore, which has the logic to determine which image to show depending on the time, steps and randomizer value:

  • The number of steps decides the action level, each mapping to multiple actions.
  • Within that level, an action is picked randomly.
  • Within that action, the time determines the image for the animation frame.

The watch face calls actionStore.getImage(time, steps, randomizerValue) to get the image file name. In the junit tests, various values of time, steps and randomizerValue are passed to that function, and the resulting image file names are verified.

Instrumentation testing

Besides verifying the logic, I also want to visually inspect the rendered bitmaps. The ui module has a Renderer class with a function drawWatchFace(canvas, steps, action, time, batteryPercent). I test this function by adding an InstrumentationTestCase to the mobile module, which enumerates all possible actions and write the animation frames to sdcard. I then combine them into animated gifs for visual inspection.

Since the wear module also uses this Renderer class from the ui module, I am confident that the layout for all the different animation frames are good. Plus, I get to see all the cute actions Fit Cat does!