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

Testing Android apps with Kotlin

Testing Android apps with Kotlin

This talk covers what to test, how to test, what good unit tests are and how you can achieve nice tests using KotlinTest (and mockk). It covers unit tests mostly since I consider them to be much more important and more neglected than integration and UI tests. Koin was left out since Arnaud Guiliani gave a dedicated Koin talk at the same meetup.

Wolfram Rittmeyer

July 30, 2019
Tweet

More Decks by Wolfram Rittmeyer

Other Decks in Programming

Transcript

  1. Why tests? • Less manual testing • Safety net when

    refactoring and maintaining • Helps flesh out structure • Helps create a clean API • Can be the spec of the code @RittmeyerW
  2. Why tests? • Less manual testing • Safety net when

    refactoring • Helps flesh out structure • Helps create a clean API • Can be the spec of the code @RittmeyerW
  3. To me, legacy code is simply code without tests. @RittmeyerW

    Michael C. Feathers, Working Effectively With Legacy Code
  4. Good unit tests, part I • Automated and repeatable •

    Easy to implement • Runs quickly • Consistent in results • Fully isolated @RittmeyerW
  5. Good unit tests, part II • Can I run all

    the unit tests I’ve written in no more than a few minutes? • Can I run all the unit tests I’ve written at the push of a button? • Can I write a basic test in no more than a few minutes @RittmeyerW Roy Osherove: The Art of Unit Testing
  6. Why KotlinTest? • Two reasons: – It‘s help you write

    nicely structured tests – It‘s helps you write clean assertions @RittmeyerW
  7. Specification in detail • Multiple styles – StringSpec – ShouldSpec

    – BDD-Spec – Feature-Spec – And more... @RittmeyerW
  8. Matchers • Two styles – Infix • someString should startWith(„prefix“)

    – Extension functions • someString.shouldStartWith(„prefix“) • Negation • someString shouldNot startWith(„prefix“) @RittmeyerW
  9. Matchers – and more • Collections • Strings • Integers

    / floating point numbers • URIs • Date values • and more @RittmeyerW
  10. Test one thing only! • Helps to name the test

    properly • Helps to find the root cause of failures faster • Indicator of testing multiple things: – Too many asserts per test @RittmeyerW
  11. You should run additional concern checks in separate, self-contained unit

    tests so that you can see what really fails. @RittmeyerW Roy Osherove, The Art of Unit Testing
  12. Property based testing • Populates properties with random values •

    Uses reasonable edge cases • You can create custom generators @RittmeyerW
  13. Table-driven testing • You have parameters and expected results •

    Useful for on device calculations @RittmeyerW
  14. Problems • No instrumentation tests with KotlinTest • Not always

    properly displayed in IDE • IDE support is missing – Especially jump to source • Plugin available, but still buggy @RittmeyerW
  15. What else? • mockk – Mocking lib • Koin –

    Dependency injection @RittmeyerW
  16. UI Tests • Robot pattern or • Kakao with screens

    / page objects • But @RittmeyerW
  17. UI Tests • Not needed for all kind of integration

    tests • Some can be done with unit tests • For example Retrofit integration • But separate those since they last longer! @RittmeyerW
  18. Robot pattern • Made popular by Jake Wharton • Variation

    of page object pattern • Uses DSLish constructs @RittmeyerW
  19. Starting with the presenter • I happen to start with

    the presenter • Needed – Presenter / ViewModel (Object under test) – View – Navigator – Interactor for non-view related app logic @RittmeyerW
  20. Starting with the presenter • Assertion done via – View

    – Navigator • Normally not via interactor @RittmeyerW
  21. Interactor • Assertions might be done differently to those of

    the presenter • Either result (sealed objects) or • Interaction with mocked objects is tested @RittmeyerW
  22. General guideline • Try to test interactions as little as

    possible • Try to concentrate on results instead • Alas, it‘s not always possible @RittmeyerW
  23. And what about the view? • Initially plenty of TODO(whatever)

    calls • Implementing them is usually trivial • Sometimes requires adjustments to presenter @RittmeyerW
  24. And what about the view? • Not part of unit

    test • Espresso tests with robot pattern – To test navigation – Interaction on one screen • e.g. visibility modifications – Based on mocks @RittmeyerW
  25. And what about the view? • Used sparingly • Consider

    splitting up in two sets: – One for dev testing • Failures do trigger notifications of team – One for pre-prod testing that is kind of supervised automatic testing • Failures do not trigger notifications of team @RittmeyerW
  26. There are two ways to make changes to a system:

    1. Edit and Pray 2. Cover and Modify @RittmeyerW https://barryosull.com/blog/notes-from-working-effectively-with-legacy-code/