Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Why tests? @RittmeyerW

Slide 3

Slide 3 text

Why automated tests? @RittmeyerW

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

To me, legacy code is simply code without tests. @RittmeyerW Michael C. Feathers, Working Effectively With Legacy Code

Slide 7

Slide 7 text

Which tests? @RittmeyerW

Slide 8

Slide 8 text

Which tests? @RittmeyerW https://martinfowler.com/bliki/TestPyramid.html

Slide 9

Slide 9 text

Which tests? @RittmeyerW https://watirmelon.blog/testing-pyramids/

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Good unit tests, part I ● Automated and repeatable ● Easy to implement ● Runs quickly ● Consistent in results ● Fully isolated @RittmeyerW

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Why KotlinTest? @RittmeyerW

Slide 14

Slide 14 text

Why KotlinTest? ● Two reasons: – It‘s help you write nicely structured tests – It‘s helps you write clean assertions @RittmeyerW

Slide 15

Slide 15 text

Specification in Detail @RittmeyerW

Slide 16

Slide 16 text

Specification in detail ● Multiple styles – StringSpec – ShouldSpec – BDD-Spec – Feature-Spec – And more... @RittmeyerW

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

Assertions @RittmeyerW

Slide 23

Slide 23 text

Matchers ● Two styles – Infix ● someString should startWith(„prefix“) – Extension functions ● someString.shouldStartWith(„prefix“) ● Negation ● someString shouldNot startWith(„prefix“) @RittmeyerW

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

Matchers - General @RittmeyerW shouldBe() shouldBeTypeOf() shouldBeInstanceOf() shouldBeNull() shouldBeSameInstanceAs() shouldBeOneOf() shouldHaveSameHashCodeAs()

Slide 26

Slide 26 text

Matchers – and more ● Collections ● Strings ● Integers / floating point numbers ● URIs ● Date values ● and more @RittmeyerW

Slide 27

Slide 27 text

Matchers – Collection Inspectors forAll() forNone() forOne() forAtMostOne() forAtMost(n) ... @RittmeyerW

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

Multivalue tests @RittmeyerW

Slide 34

Slide 34 text

Property based testing ● Populates properties with random values ● Uses reasonable edge cases ● You can create custom generators @RittmeyerW

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

Table-driven testing ● You have parameters and expected results ● Useful for on device calculations @RittmeyerW

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

Problems @RittmeyerW

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

What else? @RittmeyerW

Slide 41

Slide 41 text

What else? ● mockk – Mocking lib ● Koin – Dependency injection @RittmeyerW

Slide 42

Slide 42 text

mockk ● Mocking library with Kotlin in mind ● Easier to use than Mockito @RittmeyerW

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

UI Tests @RittmeyerW

Slide 46

Slide 46 text

UI Tests ● Robot pattern or ● Kakao with screens / page objects @RittmeyerW

Slide 47

Slide 47 text

UI Tests ● Robot pattern or ● Kakao with screens / page objects ● But @RittmeyerW

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

Robot pattern ● Made popular by Jake Wharton ● Variation of page object pattern ● Uses DSLish constructs @RittmeyerW

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

My TDD(ish) workflow @RittmeyerW

Slide 55

Slide 55 text

My TDD(ish) workflow ● Let‘s consider starting with a login screen @RittmeyerW

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Starting with the presenter ● Assertion done via – View – Navigator ● Normally not via interactor @RittmeyerW

Slide 58

Slide 58 text

Interactor ● Assertions might be done differently to those of the presenter ● Either result (sealed objects) or ● Interaction with mocked objects is tested @RittmeyerW

Slide 59

Slide 59 text

General guideline ● Try to test interactions as little as possible ● Try to concentrate on results instead ● Alas, it‘s not always possible @RittmeyerW

Slide 60

Slide 60 text

And what about the view? ● Initially plenty of TODO(whatever) calls ● Implementing them is usually trivial ● Sometimes requires adjustments to presenter @RittmeyerW

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

Why only TDDish? @RittmeyerW

Slide 64

Slide 64 text

Why only TDDish? ● It does not help flesh out architecture @RittmeyerW

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

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/

Slide 69

Slide 69 text

No content