-
An Introduction to Unit Testing on Android
2015-05-29
Yesterday at IO Extended Orlando, I gave a talk on testing. What follows is a written version of the presentation I gave. Android 1.2 introduced unit testing support. Now, we can run junit tests on the jvm while we’re developing our apps. During my talk, we’ll discuss the following questions: Why should anyone care about this new feature? What the heck is unit testing anyways? Briefly, I’ll also mention some of the challenges of writing unit tests for Android. …
-
What I've Learned From Trying to Make An Android App Unit Testable
2015-05-22
For the past few posts, I’ve introduced and showed how we would apply The Square Way of building Android applications. The primary motivation for The Square Way was to increase the unit testability of our applications. As I stated in the introduction to this series, most tests in Android are slow, instrumentation tests and/or tests that rely on third-party frameworks like Roboletric. The Square Way was supposed to help us write fast unit tests that didn’t rely on any third-party frameworks. Now that we’ve discussed why unit testing in Android is so difficult and seen how The Square Way resolves those difficulties, we are finally in a position to assess The Square Way as a whole as a method of creating unit testable Android applications. That assessment is the subject of this article. My assessment consists of the following three claims: Removing all compile time dependencies on the Android SDK is not necessary for us write fast unit tests for Android. (Its also not really a practical thing to try to do anyway.) Provided that we redefine The Square Way so that it does not require us to remove compile-time dependencies on the Android SDK, the only problem that arises when trying to apply The Square Way is simply writing all of boilerplate code. Fortunately, much of this boilerplate can be written for us by Android Studio. Dependency Injection is really the main “active ingredient” that allows The Square Way enhance the unit testability of our applications. …
-
Android Unit Testing Guides
2015-05-09
In my last post, I showed how we can apply The Square Way to UI app component classes. More specifically I showed how The Square Way would have us rewrite the SessionDetailActivity so that we could unit test its onStop() method. At the end of my last post, I said that I’d be spending this and the next post doing an overall assessment of The Square Way. I actually won’t be doing that this post. I’ll be postponing the overall assessment of The Square Way until the next few posts. Instead, what I want to do in this post is simply present a few unit-testability guides. These cheatsheets summarize much of what’s been covered in the past few posts and provide you with simplified steps to follow if you are interested in enhancing your application’s unit-testability via The Square Way. …
-
How to Make Our Android Apps Unit Testable (Pt. 2)
2015-05-08
In my last post, I introduced the “The Square Way” of structuring our android code. I said that The Square Way is a generalization of the approach that Square used to make the logic within their Fragments unit testable. I also showed how The Square Way would have us rewrite the SessionCalendarService within Google’s IOSched app so that we could unit test the business logic within it. As we’ll see in this post, The Square Way also makes it easier/possible for us to unit test UI app component business logic. …
-
How to Make Our Android Apps Unit Testable (Pt. 1)
2015-05-01
Unit testing Android apps is hard, and sometimes it can be impossible. For the past two posts, I’ve been explaining why android unit testing is so difficult. The main conclusion from the last post is that it is difficult/impossible to unit test our Android applications because of the way we are encouraged to structure them. Google seems to want us to put our business logic in app component classes (e.g., Activitys, Fragments, Services, etc.). This approach to writing Android applications is what I have been calling the “standard way.” In this post, I outline an alternative approach to structuring Android applications that will make it easier to unit test them. As I pointed out in the introduction to this series, the approach that I suggest is a generalization of the approach that Square uses to remove Fragments from their applications. Since this approach is inspired by the folks at Square, I will call it “the square way.” The heart of the square way way is this: remove all business logic from app component classes (e.g., Activitys, Fragments, Services) and place that logic into “business objects,” POJO objects whose dependencies are injected, android-specific implementations of android-agnostic interfaces. If we follow the square way of developing our apps, we will be in a better position to unit test them. In this post, I explain how the square way would have us refactor non-UI app components like the SessionCalendarService I’ve been discussing for the past few posts. …
-
Why Android Unit Testing Is So Hard (Pt. 2)
2015-04-24
Edit: In the post that concludes this series, I point out that making unit testable Android apps does not require us to remove compile-time dependencies on the Android SDK and that attempting to do so is impractical anyway. Ignore anything in this post that suggests otherwise. In my last post, I showed that even the (intelligent) engineers over at Google have written some Android code that is simply untestable. More specifically, I showed that there’s no way to unit test the SessionDetailActivity’s onStop() method. I also gave a specific diagnosis for the untestability of onStop(): we can’t complete the arrange- and assert-steps of a test against onStop() because there is no way to alter the pre-act-state, nor is there a way to access the post-act-state for a test of onStop(). I ended the last post by claiming that some properties of the Android SDK, along with the standard way we are encouraged to structure our android apps, encourage us to write code that is difficult/impossible to unit test and by promising that I’d elaborate more on that claim in this post. Before I do that, let me say again that showing that the difficulty of testing Android applications is caused by the standard structure of android apps is important for the overarching goal of this series of articles. This series is an attempt to argue that we should consider restructuring our applications so that they do not explicitly depend on the Android SDK and its an attempt to present a robust architecture that will enhance the testability of Android applications. You can read the introduction to this series here. With that said, I can move on to trying to demonstrate the central claim of this post. There’s a standard way of developing android applications. Sample code and open source code alike both place an app’s business logic within Android app component classes, namely, Activities, Services, and Fragments. Going forward, I’m going to refer to this practice as “the standard way.” Here’s the central claim of this post: As long as we follow the “standard way”, we’re going to write code that’s either difficult or impossible to unit test. In other words, the untestable code that I pointed out in my last article is not a fluke. The standard way prevents us from unit testing key pieces of our applications. …
-
Why Android Unit Testing is so Hard (Pt 1)
2015-04-17
Edit: In the post that concludes this series, I point out that making unit testable Android apps does not require us to remove compile-time dependencies on the Android SDK and that attempting to do so is impractical anyway. Ignore anything in this post that suggests otherwise. Unit testing your Android apps can be extremely difficult. As I suggested in the introduction to this series, it seems clear that there’s widespread agreement on this. The many folks who responded to my introductory post, moreover, seemed to reinforce my claim that Android unit testing is tough: So, Android unit testing is hard. That much is clear. Why Android unit testing is so difficult, however, is less clear. Its true that a part of the difficulty with Android unit testing has to do with the nonsense that you have to overcome to get Roboletric started so that you can run your tests at a decent speed, but I think that there’s a deeper reason why we are having a hard time testing our applications: the way that Google has written the Android SDK and the way that Google encourages us to structure our applications makes testing difficult and, in some cases, impossible. I realize that this is a bold claim, so I will spend the entire post trying to establish it. In the following post, I’ll try to say more about how the “standard” way of developing Android applications encourages us to write code that is difficult/impossible to write sensible unit tests against. These posts are a part of a series in which I’m exploring the viability of enhancing the testability of Android applications by restructuring them so that application code does not directly depend on the Android SDK. Showing why the standard architecture for Android development makes testing difficult will both motivate and inform my alternative proposal for structuring Android applications, a proposal that I will outline in the fourth post of the series. …
-
Against Android Unit Tests
2015-04-11
Edit: Since I’ve written this, I’ve come to realize that making unit testable Android apps does not require us to remove compile-time dependencies on the Android SDK. I talk about this realization in the post that concludes this series. Even the best among us admit that they struggle with testing their Android apps. Jake Wharton has said explicitly that the Android platform has traditionally been very difficult to test.¹ In the inaugural episode of their (excellent) podcast, Don Felker and Kaushik Gopal have echoed similar sentiments.…
-
Don't call it "MVP"
2015-04-06
Lately there’s been a lot of discussion about an alternative architectural pattern for Android development. The acronym that’s being used to denote this alternative pattern is “MVP.” I think that “MVP” is an inaccurate and confusing designation for this pattern. In this post, I will say why I think “MVP” is a bad name for the pattern, and I’ll suggest a different name for referring to it. What is “MVP?” There are plenty of blog posts out there that describe the “MVP” pattern, so I’m not going to do that here.…
-
How to Keep your RxJava Subscribers from Leaking
2015-03-24
Edit: Shortly after writing this, I realized that the solution that I present here isn’t very good. I’m leaving it here just in case it can serve as a building block for better solutions. Sometimes you don’t have control over the lifecycle of your Subscribers. In these cases, to avoid leaking your Subscriber, you have to unsubscribe from your Observable when you’re notified that your Subscriber is about to be destroyed.…