Passive View

Chuck Greb
Android Testing
Published in
3 min readSep 19, 2017
Bamboo” by Jason Wong licensed under CC BY-NC-ND 2.0

Passive View is the concept that logic in UI code should be minimized. This idea is also sometimes referred to as Humble View.

View code is typically the most difficult part of an application to test. UI tests are slow, brittle, and expensive.

In Android this is especially true. Tests written using Espresso or UI Automator require compiling, dexing, and installing not one but two applications on an emulator or physical device.

This unfortunate truth is often mitigated by extracting presentation logic out of the view layer and into a controller, presenter, or view model where it can be more easily maintained and tested.

Controllers, presenters, and view models all play a similar role in clean architecture but there are subtle differences in the flow of information.

Model View Controller (MVC)

MVC architecture implies a one-way flow of information. View events are handled by framework classes (activity, fragment, or custom view) and then forwarded to the controller.

The controller performs input validation and then passes the relevant data to the domain model. Finally, an update is triggered in view layer using the observer pattern and/or data binding.

MVC uses a one-way flow of information

Model View Presenter (MVP)

MVP architecture uses a bi-directional flow of information. UI events are forwarded from the framework classes to the presenter for input validation. The presenter relies on the domain model to perform business logic and/or mutation of state.

The primary difference between a presenter and a controller is that the presenter then performs any presentation logic associated with the new state and then calls back to the view layer through an interface.

MVP pushes updates back to the view via an interface

Model View ViewModel (MVVM)

MVVM also uses bi-direction flow of information, but unlike MVC there is no dependency between the view and the domain model.

Rather the view maintains two connections to the view model class. One is to forward user input and UI events. The other is an observer that listens for changes in the view model state to trigger an update to the display.

In MVVM, the view observes changes in the view model

Sit Down, Be Humble

Of these three architectures, the only one that allows for a truly passive (humble) view is MVP.

Why?

In both MVC and MVVP, some logic must exist in the view to synchronize screen state and session state. Whether it is data binding expressions in the layout, or callbacks registered by activity as an observer, this logic is impossible to eliminate and difficult to test.

With MVP, synchronization is handled by the presenter resulting in a legit dumb view. The tradeoff here is that testing becomes slightly more verbose since the view must be replaced by a stub that implements the same interface in the test harness.

Should I use Passive View?

The answer to this question depends on the nature of your individual application.

For simpler apps, MVC or MVVM can be sufficient as sync logic will be minimal and unit tests will requires less boilerplate code to implement.

For more complex applications, I always recommend using a Passive View. As sync logic grows in complexity testing it becomes increasingly vital and is well worth the tradeoff of maintaining a test double of the view driver.

That’s all for today. As always, happy testing!

This post is part of a series on clean architecture that explores how classic software design principles can be applied to modern Android development.

If you found this article helpful, please give it some applause 👏 to help others find it. Feel free to leave a comment below.

--

--

Chuck Greb
Android Testing

Mission-driven engineering leader. Community organizer. Digital minimalist.