Automate UI testing with predictable state and flexibility, off the UI thread Goals Fully automate UI testing (Espresso on Android) All computation (except view access) done on a background thread A front-end architecture that can fit any platform. The same ideas apply to iOS, Android, & the web, thanks to ’s cross-platform nature. ReactiveX A UI layer that can adapt to anything. Edge cases, new requirements, and increased complexity do not require refactoring This article covers goals #1 and #2. In a future post, I’ll dig into why #4 is true. Model View Intent (MVI) I definitely recommend checking out Hannes Dorfmann’s amazing on MVI and Android. I won’t get in to what Model View Intent is, but rather my specific implementation of it. blog series In a nutshell, we will merge input from our data layer with user input to output a continuously updated over time, rendering each new instance of a onto our / . ViewState ViewState Ui View Demo App — a “Deck of Cards” Here’s the simplified implementation of . StateRenderer<DealCardsUi.State> Using Rx’s Schedulers and observing the latest , we achieve Goal #2 — stay off the UI thread as much as possible. ViewState Automated UI Testing All of our classes have the following function — a single point of entry for displaying information to the user. Ui fun render(state: ViewState) Testing is reduced to a simple input/output function. — the . Grab a reference to your , and call the function. Input ViewState Ui ui.render(viewState) — the . Use Espresso to verify the looks as expected. Output Ui Ui Want to test configuration changes? Call and verify the output is unchanged again. activity.recreate() Meet the following requirements to simplify testing. Unhook (disable) every from activating during testing, and/or disable your disk/network layer. Presenter Keep navigation functional without presenters. Navigation via intents simplifies this. Ability to get a reference to your view. This could be an , , , , etc - but you must be able to call your function. Activity Fragment ViewGroup Controller view.render(state: ViewState) Conclusion I truly believe this style of view architecture is the natural evolution over MVP, MVVM, etc. A single allows for predictable state and maximum testability. ViewState In future articles, I will dig deeper into other components, such as the business logic that is responsible for the . ViewState Catch the conversation on Reddit All source is available on . GitHub Shoutout to the many pioneers of reactive programming that have made this architecture possible! Additional resource — watch Jake Wharton’s awesome with Rx. talk on managing state