Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Testable Android Architecture (Android Makers France)

Testable Android Architecture (Android Makers France)

Today we have a variety of automated testing tools available for Android including JUnit, Mockito, Robolectric, Espresso, UI Automator and more.

But how can we design our applications to leverage each tool most effectively and at the same time ensure our code is readable, flexible, and maintainable?

Chuck Greb

April 11, 2017
Tweet

More Decks by Chuck Greb

Other Decks in Technology

Transcript

  1. Testable Android
    Architecture
    11 April 2017 / Chuck Greb / @ecgreb

    View full-size slide

  2. Clean code
    Software Craftsmanship

    View full-size slide

  3. The only thing that is
    constant is change.

    - Heraclitus

    View full-size slide

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


    - Robert M. Pirsig

    View full-size slide

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

    View full-size slide

  6. A brief history of
    Android development

    View full-size slide

  7. https://en.wikipedia.org/wiki/Android_version_history

    View full-size slide

  8. Activity
    Activity
    Lifecycle
    System
    Services

    View full-size slide

  9. Activity
    EditText
    Button
    Activity
    Lifecycle
    System
    Services

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size 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 full-size slide

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

    View full-size slide

  16. A cleaner approach...

    View full-size slide

  17. Activity Logic

    View full-size slide

  18. Activity Logic
    Data

    View full-size slide

  19. Activity Logic
    Data
    View

    View full-size slide

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


    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  29. → UI end-to-end tests through the user
    interface. Simulates actual usage of the
    app. Often slow, expensive, and brittle.
    → Service provide many of the advantages
    of end-to-end tests but avoid many of the
    complexities of dealing with UI
    frameworks.
    → Unit the smallest testable parts of an app
    are individually and independently
    exercised for proper operation.
    Test Pyramid

    View full-size slide

  30. If you get a failure in a high
    level test, not just do you
    have a bug in your functional
    code, you also have a missing
    or incorrect unit test.

    - Martin Fowler

    View full-size slide

  31. 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
    Unit Test Rules

    View full-size slide

  32. → UI end-to-end tests run on an emulator
    or device using the Espresso framework.
    → Integration using Robolectric tests can
    be run in the local JVM against the real
    Android JARs mocking only UI and
    system hardware components.
    → Unit use JUnit and Mockito plus a special
    mockable version of the Android JAR to
    test app code in isolation in the local
    JVM.
    Android Test Pyramid

    View full-size slide

  33. Unit Tests
    JUnit + Mockito (JVM)

    View full-size slide

  34. Mock
    Service
    Mock
    Storage
    Test
    Controller
    Presenter
    Model
    Controller
    JUnit
    TestRunner
    Thread
    run()

    View full-size slide

  35. Integration Tests
    Robolectric

    View full-size slide

  36. Activity
    Robolectric
    TestRunner
    Robolectric
    Runtime
    Environment
    Simulated
    Input
    View
    Button
    EditText
    Input
    Validation
    Mock
    Service
    Mock
    Storage
    Presenter
    Model
    Thread
    run()

    View full-size slide

  37. UI Tests
    Espresso

    View full-size slide

  38. Web
    Service
    Storage
    Activity
    Activity
    Lifecycle
    System
    Services
    Presenter
    View Model
    Controller
    Button
    EditText
    Thread
    Input
    Validation
    start()
    Android
    JUnit4
    TestRunner

    View full-size slide

  39. → Configuration Changes
    → View Presenters
    → Legacy Code
    FAQ
    Frequently Answered Questions

    View full-size slide

  40. Configuration Changes

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  43. View Presenters

    View full-size slide

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

    View full-size slide

  45. → Code that does not have tests was
    probably not written to be testable
    → Do not set aside dedicated time to
    “refactor” and “improve test coverage”
    → Test any new code that is added
    → Test any code around new code that is
    added
    → Use seams to break dependencies,
    decouple components, and modularize
    your code base
    Legacy Code
    Code without tests

    View full-size slide

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

    View full-size slide

  47. → Clean architecture can help your code be
    more flexible, maintainable, and
    testable.
    → Choose an architecture appropriate to
    your use case.
    → Write unit, integration, and UI tests that
    work in concert with your architecture.
    → Don’t be overly dogmatic-- software
    development is an art and a science.
    Conclusion
    Which architecture and testing tools should I use?

    View full-size slide

  48. Merci à vous
    11 April 2017 / Chuck Greb / @ecgreb

    View full-size slide