$30 off During Our Annual Pro Sale. View Details »

Testable Android Architecture (Part 2)

Chuck Greb
November 15, 2016

Testable Android Architecture (Part 2)

We have so many testing tools for Android now including JUnit, Mockito, Robolectric, and Espresso. But how can you design your application to leverage each one most effectively? This talk introduces a modified version of Model View Presenter (MVP) to help organize your code to be more flexible, maintainable, and testable.

The first half of this talk will recap my presentation from Droidcon NYC 2016. The second half will explore advanced use cases, in-depth code samples, and audience Q&A.

Chuck Greb

November 15, 2016
Tweet

More Decks by Chuck Greb

Other Decks in Technology

Transcript

  1. Testable Android
    Architecture
    (Part 2)
    15 Nov 2016 / Chuck Greb

    View Slide

  2. Clean code
    Software Craftsmanship

    View Slide

  3. Art is anything you can do
    well. Anything you can do
    with Quality.


    - Robert M. Pirsig

    View Slide

  4. View Slide

  5. → MVC Model View Controller
    → MVP Model View Presenter
    → MVVM Model View ViewModel
    Clean Architecture
    Design patterns

    View Slide

  6. Building your first app

    View Slide

  7. Activity

    View Slide

  8. Activity
    Activity
    Lifecycle
    System
    Services

    View Slide

  9. Activity
    EditText
    Button
    Activity
    Lifecycle
    System
    Services

    View Slide

  10. Activity
    EditText
    Button
    Web
    Service
    Storage
    AsyncTask
    Activity
    Lifecycle
    System
    Services

    View Slide

  11. Fragment
    Activity
    EditText
    Button
    Web
    Service
    Storage
    AsyncTask
    Activity
    Lifecycle
    System
    Services
    Fragment
    Fragment
    Lifecycle

    View Slide

  12. Fragment
    Activity
    EditText
    Button
    Web
    Service
    Storage
    AsyncTask
    Activity
    Lifecycle
    System
    Services
    Fragment
    Fragment
    Lifecycle
    User
    Input
    Input
    Validation

    View Slide

  13. Fragment
    Activity
    Web
    Service
    Storage
    AsyncTask
    Activity
    Lifecycle
    System
    Services
    Fragment
    Fragment
    Lifecycle
    User
    Input
    setRetainInstance(true)
    EditText
    Button
    Input
    Validation

    View Slide

  14. Fragment
    Activity
    Web
    Service
    Storage
    AsyncTask
    Activity
    Lifecycle
    System
    Services
    Fragment
    Fragment
    Lifecycle
    User
    Input
    setRetainInstance(true)
    Intent
    Parcelable
    Extras
    EditText
    Button
    Input
    Validation

    View Slide

  15. Web
    Service
    Storage
    Activity
    Fragment
    Fragment
    AsyncTask
    setRetainInstance(true)
    Activity
    Lifecycle
    Fragment
    Lifecycle
    System
    Services
    User
    Input
    Intent
    Activity
    Instrumentation
    TestCase2
    Parcelable
    Extras
    EditText
    Button
    Input
    Validation

    View Slide

  16. View Slide

  17. There has to be a
    better way

    View Slide

  18. Activity Logic

    View Slide

  19. Activity Logic
    Data

    View Slide

  20. Activity Logic
    Data
    View

    View Slide

  21. View
    (Activity)
    Controller
    (Logic)
    Model
    (Data)
    View

    View Slide

  22. View
    (Activity)
    Presenter
    (Logic)
    Model
    (Data)
    View

    View Slide

  23. View
    (Activity)
    ViewModel
    (Logic)
    Model
    (Data)
    View

    View Slide

  24. - Phil Karlton
    There are only two hard
    problems in computer science:
    cache invalidation and naming
    things


    View Slide

  25. Clean Architecture
    Model View
    Presenter Controller
    MVP(C)

    View Slide

  26. Controller
    (Activity)
    Presenter
    (Logic)
    Model
    (Data)
    View

    View Slide

  27. Activity Presenter
    (Logic)
    Model
    (Data)
    View
    Controller

    View Slide

  28. Web
    Service
    Storage
    Activity
    Activity
    Lifecycle
    System
    Services
    User
    Input
    Presenter
    View Model
    Controller
    Button
    EditText
    Thread
    Input
    Validation
    start()

    View Slide

  29. Web
    Service
    Storage
    Activity
    Activity
    Lifecycle
    System
    Services
    User
    Input
    Presenter
    View Model
    Controller
    Button
    EditText
    Input
    Validation
    Thread
    start()

    View Slide

  30. Testings
    Models & Presenters
    JUnit + Mockito

    View Slide

  31. Mock
    Service
    Mock
    Storage
    Test
    Controller
    Presenter
    Model
    Controller
    JUnit
    TestRunner
    Runnable
    run()

    View Slide

  32. A test is not a unit test if:
    → It talks to the database
    → It communicates across the network
    → It touches the file system
    → It can't run at the same time as any of
    your other unit tests
    → You have to do special things to your
    environment (such as editing config files)
    to run it.
    Michael Feathers, 2005
    A Set of Unit Test Rules

    View Slide

  33. Testing
    Activities & Views
    Robolectric

    View Slide

  34. Activity
    Robolectric
    TestRunner
    Robolectric
    Runtime
    Environment
    Simulated
    Input
    Stub
    Presenter
    View
    Button
    EditText
    Input
    Validation

    View Slide

  35. Demo App
    https://github.com/ecgreb/mvpc

    View Slide

  36. Q & A

    View Slide

  37. What is the best way to
    manage presenter scope or
    lifecycle?


    View Slide

  38. → Global singleton
    → Scoped singleton
    → View State Manager
    Q & A
    What is the best way to manage presenter scope or lifecycle?

    View Slide

  39. Web
    Service
    Storage
    Activity
    Activity
    Lifecycle
    System
    Services
    User
    Input
    Presenter
    View Model
    Controller
    Button
    EditText
    Thread
    Input
    Validation
    start()

    View Slide

  40. Web
    Service
    Storage
    Activity
    Activity
    Lifecycle
    System
    Services
    User
    Input
    Presenter
    View Model
    Controller
    Button
    EditText
    Thread
    Input
    Validation
    start()
    ViewState
    Manager
    (VSM)

    View Slide

  41. Can a view have its own
    presenter?


    View Slide

  42. → True Model-View-Presenter
    → One presenter instance per view
    Q & A
    Can a view have its own presenter?

    View Slide

  43. View
    Presenter
    Activity
    Activity
    Lifecycle
    System
    Services
    User
    Input
    Main
    Presenter
    View
    Controller
    Button
    EditText
    Input
    Validation
    Model

    View Slide

  44. How do you communicate
    between multiple
    presenters?


    View Slide

  45. → Pass the message “around the horn”
    → Event bus
    Q & A
    How do you communicate between multiple presenters?

    View Slide

  46. Search
    View
    Search
    Presenter
    Main
    Activity
    Main
    Presenter
    Navigation
    View
    Navigation
    Presenter

    View Slide

  47. Search
    View
    Search
    Presenter
    Main
    Activity
    Main
    Presenter
    Navigation
    View
    Navigation
    Presenter
    Event
    Bus

    View Slide

  48. Eraser Map

    View Slide

  49. View Slide

  50. View Slide

  51. → Choose an architecture appropriate to
    your use case
    → Write tests that work in concert with
    your architecture
    → Don’t be overly dogmatic
    Conclusion
    So which architecture and testing strategy should I use for my app?

    View Slide

  52. Start where you are

    View Slide