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 if you think I should write it!

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 if you think I should write it!

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!

Sunday, June 28, 2015

Android Camera2 API talk

Since I started helping with GDG Boulder, I have been only organizing beginner events, especially for Android, because I sensed that the audience does not have a lot of Android experience.

At our Android Hack Night in April, someone came up to me and said, "Can we have more advanced events? I haven't been coming because I am looking for more advanced material". I did a mental face palm when I heard that. Of course! I have been organizing beginner events. Beginners come. That doesn't mean we don't have members who want advanced events. I have been hungry for advanced Android talks myself, and should have just gone for it instead of tiptoeing around imaginary audience preferences.

Camera2 API

After hearing that I happily scheduled an advanced Android talk for June. Huyen gave an informative and entertaining talk on Camera2 API, and I really enjoyed it.

Raffle for ideas

I always ask people to tell me what topics interest them, but they never actually do. This time, my friend Dave Smith said he wants to give a way a couple of Android books, so we ran a raffle. To enter, people need to put in their name and also a suggestion for future event. I collected quite a few ideas this way. Win!

Friday, June 19, 2015

Android Dialogs: Launch!

My favorite part about going to conferences is to chat with people. I learn so much by talking shop. I was chatting with my friend Huyen about that, one thing led to another, and we ended up collaborating on a YouTube channel!

I present to you Android Dialogs, where we have bite-sized conversations with people from the Android community. In our first episode, Huyen and I interviewed each other.

We talked with quite a few people at Google I/O, so stayed tuned for more! Best way to stay tuned? Subscribe:

https://www.youtube.com/channel/UCMEmNnHT69aZuaOrE-dF6ug

Yes, the URL is awful. We need 500 subscribers to get a custom one. So, subscribe, pretty please?

Monday, June 15, 2015

A day in Colorado Springs

I have been reading a lot more graphic novels since I started sketchnoting. Right now I am reading An Age of License by Lucy Knisley, a travelogue with delightful illustrations. I am not even half done, and I already wanted to make a travelogue. So I did, with my trip to Colorado Springs last weekend!