Android VIPER Tutorial

In this tutorial, you’ll become familiar with the various layers of the VIPER architecture pattern and see how to keep your app modules clean and independent. By Pablo L. Sordo Martinez.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

App performance analysis

Once completed, you should have Chucky Facts up and running as in the video.

When started, the splash-screen appears for just a few seconds, and then it jumps directly to MainActivity. A ProgressBar appears while the list gets populated. You can gracefully scroll along the list, with no lag whatsoever. The Router works seamlessly allowing smooth transitions between screens, even handling the Toolbar "Back Arrow" events.

Testing the snake

One of the main benefits of using architecture patterns like VIPER is that it allows you to isolate the business logic in the Presenter. This entity ends up knowing nothing about Android. This is rather convenient since it makes unit testing much easier, reducing the amount of mocks you need to create.

Although there is not much business logic in this sample app, it is always a good practice to include some tests (both unit and UI tests). For that reason, the starter app comes with a pair of UI tests in MainActivityInstrumentedTest, in the androidTest folder:

class MainActivityInstrumentedTest {

  @Rule
  @JvmField
  val activityTestRule = ActivityTestRule<MainActivity>(MainActivity::class.java)

  @Test
  fun testRecyclerViewIsPopulated() {  // 1

    waitForSplashScreen()

    onView(withId(R.id.rv_jokes_list_activity_main))
        .check(matches(hasDescendant(withText("2"))))
  }

  @Test
  fun testRecyclerViewItemClickLaunchesDetailActivity() { // 2

    waitForSplashScreen() // 3

    onView(withId(R.id.rv_jokes_list_activity_main))
        .perform(RecyclerViewActions.scrollToPosition<JokesListAdapter.ViewHolder>(2))
        .perform(RecyclerViewActions.actionOnItemAtPosition<JokesListAdapter.ViewHolder>(2, click()))

    assert(onView(ViewMatchers.withId(R.id.rv_jokes_list_activity_main)) == null)
  }
}

Regarding the above snippet:

  1. The first test assesses that the RecyclerView gets populated, particularly checking that there is an item showing a "2" text message. In this particular case, it relates to the second item of the list.
  2. The second test checks whether DetailActivity launches when clicking on a list item. For that purposes, the function assesses that once clicked, the RecyclerView does not show anymore.
  3. In both test functions there is a call to waitForSplashScreen() from Utils.kt, which sleeps the thread for a few seconds to skip the splash-screen lapse.

Go ahead and click the green test arrow next to MainActivityInstrumentedTest. The Espresso UI tests will run on a device or emulator and you should see them both pass.

Where To Go From Here?

You can download the fully finished sample project using the download button at the top or bottom of the tutorial.

There are lots of good references to read about architecture patterns and VIPER in particular. I personally found rather solid foundations reading articles like this one, and this other.

Taking into account the latest novelties on Android, it would be interesting for you to get your hands on the Android Architecture Components, especially on components like Room, LiveData, and Navigation Controller. Give the official documentation a go, since as usual it is superb.

If you are interested in wrapping up the sample app you have just finished, it would be interesting to incorporate Dependency Injection using a library like Dagger. That will add completeness to the example, and will also help you to get consistency on your development projects by including one of the most popular frameworks for creating well-structured code.

We hope you enjoyed this tutorial on the VIPER architecture pattern, and if you have any questions or comments, please join the forum discussion below!