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 Slide

  2. Clean code
    Software Craftsmanship

    View Slide

  3. The only thing that is
    constant is change.

    - Heraclitus

    View Slide

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


    - Robert M. Pirsig

    View Slide

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

    View Slide

  6. A brief history of
    Android development

    View Slide

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

    View Slide

  8. View Slide

  9. Activity

    View Slide

  10. Activity
    Activity
    Lifecycle
    System
    Services

    View Slide

  11. Activity
    EditText
    Button
    Activity
    Lifecycle
    System
    Services

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. 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

  17. 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 Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. View Slide

  22. A cleaner approach...

    View Slide

  23. Activity Logic

    View Slide

  24. Activity Logic
    Data

    View Slide

  25. Activity Logic
    Data
    View

    View Slide

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


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  35. View Slide

  36. → 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 Slide

  37. 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 Slide

  38. 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 Slide

  39. View Slide

  40. View Slide

  41. → 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 Slide

  42. Test Types

    View Slide

  43. Unit Tests
    JUnit + Mockito (JVM)

    View Slide

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

    View Slide

  45. View Slide

  46. View Slide

  47. View Slide

  48. View Slide

  49. View Slide

  50. Integration Tests
    Robolectric

    View Slide

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

    View Slide

  52. View Slide

  53. UI Tests
    Espresso

    View Slide

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

    View Slide

  55. View Slide

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

    View Slide

  57. Configuration Changes

    View Slide

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

    View Slide

  59. 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

  60. View Presenters

    View Slide

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

    View Slide

  62. Legacy Code

    View Slide

  63. → 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 Slide

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

    View Slide

  65. → 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 Slide

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

    View Slide