The document discusses test-driven development (TDD) on Android. It covers:
- The history and principles of TDD, including writing failing tests first and then only producing code to pass those tests.
- How TDD works in practice using the "red-green-refactor" process of writing a failing test, passing code, then refactoring.
- Benefits of TDD like fewer bugs, easier refactoring, and faster long-term development.
- Considerations for testing Android code, such as using mockable classes and avoiding direct testing of activities/fragments.
12. @PreusslerBerlin
History
• Started with test first from XP in 1999 by Kent
Beck
• Just a rediscovery:
test first was normal in early days of
programming
• Famous as TDD since Kent Becks book in 2003
13. @PreusslerBerlin
History
• Started with test first from XP in 1999 by Kent
Beck
• Just a rediscovery:
test first was normal in early days of
programming
• Famous as TDD since Kent Becks book in 2003
14. @PreusslerBerlin
History
• Started with test first from XP in 1999 by Kent
Beck
• Just a rediscovery:
test first was normal in early days of
programming
• Famous as TDD since Kent Becks
book in 2003
16. @PreusslerBerlin
The 3 rules of TDD
• You must write a failing test before you
write any production code.
• You must not write more of a test than is
sufficient to fail, or fail to compile.
• You must not write more production
code than is sufficient to make the
currently failing test pass.
nano-cycle (seconds)
17. @PreusslerBerlin
The 3 rules of TDD
• You must write a failing test before you
write any production code.
• You must not write more of a test than is
sufficient to fail, or fail to compile.
• You must not write more production
code than is sufficient to make the
currently failing test pass.
nano-cycle (seconds)
18. @PreusslerBerlin
The 3 rules of TDD
• You must write a failing test before you
write any production code.
• You must not write more of a test than is
sufficient to fail, or fail to compile.
• You must not write more production
code than is sufficient to make the
currently failing test pass.
nano-cycle (seconds)
19. @PreusslerBerlin
The 3 rules of TDD
• You must write a failing test before you
write any production code.
• You must not write more of a test than is
sufficient to fail, or fail to compile.
• You must not write more production
code than is sufficient to make the
currently failing test pass.
nano-cycle (seconds)
20. @PreusslerBerlin
Red Green Refactor
• Create a unit tests that fails
• Write just enough production code
to makes that test pass.
• Clean up the mess you just made.
micro-cycle (minutes)
21. @PreusslerBerlin
Red Green Refactor
• Create a unit tests that fails
• Write just enough production code
to makes that test pass.
• Clean up the mess you just made.
micro-cycle (minutes)
22. @PreusslerBerlin
Red Green Refactor
• Create a unit tests that fails
• Write just enough production code
to makes that test pass.
• Clean up the mess you just made.
micro-cycle (minutes)
23. @PreusslerBerlin
Red Green Refactor
• Create a unit tests that fails
• Write just enough production code
to makes that test pass.
• Clean up the mess you just made.
micro-cycle (minutes)
30. @PreusslerBerlin
Red Green Refactor
• Always be one step away from green bar
• Think of new test-> write it down
• It’s getting ugly? -> write it down
49. @PreusslerBerlin
Isn’t it slow?
Without TDD, you spend a few weeks writing
code which mostly works and spend the next
year "testing" and fixing many (but not all) of the
bugs
50. @PreusslerBerlin
Isn’t it slow?
With TDD, you spend a year writing code which
actually works. Then you do final integration
testing for a few weeks.
51. @PreusslerBerlin
Isn’t it slow?
• Single feature will take longer
• Bugfixing phase is shorter
• Debugging disappears
• Ci finds bugs before tester does
• Long term it’s much faster no more big rewrite
52. @PreusslerBerlin
Isn’t it slow?
• Single feature will take longer
• Bugfixing phase is shorter
• Debugging disappears
• Ci finds bugs before tester does
• Long term it’s much faster no more big rewrite
53. @PreusslerBerlin
Isn’t it slow?
• Single feature will take longer
• Bugfixing phase is shorter
• Debugging disappears
• Ci finds bugs before tester does
• Long term it’s much faster no more big rewrite
54. @PreusslerBerlin
Isn’t it slow?
• Single feature will take longer
• Bugfixing phase is shorter
• Debugging disappears
• Ci finds bugs before tester does
• Long term it’s much faster no more big rewrite
55. @PreusslerBerlin
Isn’t it slow?
• Single feature will take longer
• Bugfixing phase is shorter
• Debugging disappears
• Ci finds bugs before tester does
• Long term it’s much faster no more big rewrite
75. @PreusslerBerlin
val tested = spy(PrivacyPolicyActivity())
@Nested
inner class `When created` {
@Test
fun `sets viewmodel`() {
tested.onCreate(null)
verify(tested)
.setContentView(R.layout.main)
}
}
Does this work?
76. @PreusslerBerlin
Android SDK under test
• Android classes can be loaded on JVM:
build/generated/mockable-android-XX.jar
• Removes finals and ALL the code!
77. @PreusslerBerlin
Android SDK under test
• Empty methods with default return values
android {
…
testOptions {
unitTests.returnDefaultValues = true
}
-> no code will run
78. @PreusslerBerlin
The problem of v4… Activity
• mockable.jar not existing for libraries,
including support library L
-> real code will run
79. @PreusslerBerlin
The problem of v4… Activity
• Helper method
fun <T : FragmentActivity> T.prepareForTest(): T {
…
whenever(supportFragmentManager).thenReturn(mockSupportFragmentManager)
whenever(fragmentManager).thenReturn(mockFragmentManager)
whenever(layoutInflater).thenReturn(mockLayoutInflater)
}
85. @PreusslerBerlin
Avoid activity and fragment code
• Use life cycle aware components!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
observeLifecycleIn(viewModel)
}
@OnLifecycleEvent(ON_START)
fun onStart() {
….
}
86. @PreusslerBerlin
Avoid activity and fragment code
• Testing android view classes are hard
• Avoid needing to test them!
• ViewModel encapsulates view state testable
• Use the power of data binding
87. @PreusslerBerlin
Avoid activity and fragment code
• Testing android view classes are hard
• Avoid needing to test them!
• ViewModel encapsulates view state testable
• Use the power of data binding
88. @PreusslerBerlin
Avoid activity and fragment code
• Testing android view classes are hard
• Avoid needing to test them!
• ViewModel encapsulates view state testable
• Use the power of data binding
89. @PreusslerBerlin
Avoid activity and fragment code
• Testing android view classes are hard
• Avoid needing to test them!
• ViewModel encapsulates view state testable
• Use the power of data binding
102. @PreusslerBerlin
Tired of issues like
java.lang.NullPointerException
at
org.robolectric.manifest.MetaData
.init(MetaData.java:55)
at
org.robolectric.manifest.AndroidM
anifest.initMetaData(AndroidManif
est.java:377)....
?
Sleepy by Tomas; flickr.com/photos/tma/2438467223; CC 2.0
Don’t spent more time
fixing your test setup
than fixing your app
Sleepy by Tomas; flickr.com/photos/tma/2438467223; CC 2.0
Still valid?
106. @PreusslerBerlin
Robolectric 4
• Robolectric is just another “android device”
when using Espresso like API
• Not compatible with Junit5
• More stable now as of new API?!
• Still slower
108. @PreusslerBerlin
SPEED!
• Build speed is important
• Test new features in separate module!
• Tip: Keep Robolectric tests in separate test
folder:
test, androidTest, sharedTest
122. @PreusslerBerlin
TDD and tests
• Kent Beck spoke about behavior of the system
in his TDD book
• A “unit” does not mean every class/method!
Unit came from Blackbox!
• TDD tests behaviors not implementation details!
• What your software does, is stable!
How it does this, is unstable!
TDD what went wrong: https://www.youtube.com/watch?v=EZ05e7EMOLM
123. @PreusslerBerlin
TDD and tests
• Kent Beck spoke about behavior of the system
in his TDD book
• A “unit” does not mean every class/method!
Unit came from Blackbox!
• TDD tests behaviors not implementation details!
• What your software does, is stable!
How it does this, is unstable!
TDD what went wrong: https://www.youtube.com/watch?v=EZ05e7EMOLM
124. @PreusslerBerlin
TDD and tests
• Kent Beck spoke about behavior of the system
in his TDD book
• A “unit” does not mean every class/method!
Unit came from Blackbox!
• TDD tests behaviors not implementation details!
• What your software does, is stable!
How it does this, is unstable!
TDD what went wrong: https://www.youtube.com/watch?v=EZ05e7EMOLM
125. @PreusslerBerlin
TDD and tests
• Kent Beck spoke about behavior of the system
in his TDD book
• A “unit” does not mean every class/method!
Unit came from Blackbox!
• TDD tests behaviors not implementation details!
• What your software does, is stable!
How it does this, is unstable!
TDD what went wrong: https://www.youtube.com/watch?v=EZ05e7EMOLM
130. @PreusslerBerlin
If it's worth building,
it's worth testing
If it's not worth testing,
why are you wasting your time
working on it?
131. @PreusslerBerlin
If it's worth building,
it's worth testing
If it's not worth testing,
why are you wasting your time
working on it?
132. @PreusslerBerlin
TDD on Android?
• Its possible!
• Might feel extreme
• But it’s fun!
https://www.flickr.com/photos/chefranden/14838138493
133. More resources
• TDD what went wrong:
https://www.youtube.com/watch?v=EZ05e7EMOLM
• The three laws of TDD by Uncle Bob
https://www.youtube.com/watch?v=AoIfc5NwRks
• TDD for those who don't need it
https://www.youtube.com/watch?v=a6oP24CSdUg
• Test Driven Development by Example (Kent Beck)
137. @PreusslerBerlin
What about architecture?
• TDD does not replace Architecture and Design
• Have a vision in your head
• NO big up front design
• Defer architecture decisions as long as possible
138. @PreusslerBerlin
What about architecture?
• TDD does not replace Architecture and Design
• Have a vision in your head
• NO big up front design
• Defer architecture decisions as long as possible
139. @PreusslerBerlin
What about architecture?
• TDD does not replace Architecture and Design
• Have a vision in your head
• No big up front design
• Defer architecture decisions as long as possible
140. @PreusslerBerlin
What about architecture?
• TDD does not replace Architecture and Design
• Have a vision in your head
• No big up front design
• Defer architecture decisions as long as possible