Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
The Importance of Being Tested
Roberto Orgiu
October 21, 2021
Programming
0
130
The Importance of Being Tested
Slides of the talk I gave at Droidcon Berlin 2021
Roberto Orgiu
October 21, 2021
Tweet
Share
More Decks by Roberto Orgiu
See All by Roberto Orgiu
Wellness & Droid
tiwiz
0
11
Behind the curtains
tiwiz
0
12
An Android Dev start to Kotlin MPP
tiwiz
0
56
Fantastic API and where to find them
tiwiz
0
26
Flipping the Koin @ GDG Dev Party
tiwiz
1
27
Flipping the Koin
tiwiz
2
88
Trip into the async world @ NYC Kotlin Meetup
tiwiz
0
49
Trip into the async world
tiwiz
1
62
GraphQL IRL (Android Makers)
tiwiz
0
93
Other Decks in Programming
See All in Programming
VisualProgramming_GoogleHome_LINE
nearmugi
1
130
短納期でローンチした新サービスをJavaで開発した話/launched new service using Java
eichisanden
5
1.8k
Web API連携でCSRF対策がどう実装されてるか調べた / how to implements csrf-detection on Web API
yasuakiomokawa
2
170
One does not simply: migrating to Android 12 🤯
oleur
1
120
Amazon ECSのネットワーク関連コストの話
msato
0
610
Power Automateドリブンのチームマネジメント
hanaseleb
0
170
How we run a Realtime Puzzle Fighting Game on AWS Serverless
falken
0
240
言語処理ライブラリ開発における失敗談 / NLPHacks
taishii
1
420
Custom Design Systems in Compose UI
rharter
5
510
ドメインモデル方式のクラス設計 座談会
masuda220
PRO
3
1k
A Philosophy of Software Design 後半
yosuke_furukawa
PRO
8
2.5k
Amazon Aurora の v1 が EOL になるので 10 クラスタアップグレードして出てきたノウハウ
dekokun
0
830
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
337
17k
What's new in Ruby 2.0
geeforr
336
30k
The Brand Is Dead. Long Live the Brand.
mthomps
46
2.7k
No one is an island. Learnings from fostering a developers community.
thoeni
9
1.1k
jQuery: Nuts, Bolts and Bling
dougneiner
56
6.4k
Building an army of robots
kneath
299
40k
Streamline your AJAX requests with AmplifyJS and jQuery
dougneiner
126
8.5k
Side Projects
sachag
450
37k
Ruby is Unlike a Banana
tanoku
91
9.2k
A better future with KSS
kneath
225
15k
In The Pink: A Labor of Love
frogandcode
131
21k
What’s in a name? Adding method to the madness
productmarketing
11
1.6k
Transcript
Roberto Orgiu | Senior Android Engineer @ NYTimes | @_tiwiz
The importance of being tested
What is testing about?
Correctness Functioning
Is everything testable?
class Repository { private val dep = Dependency( ) fun
fetch() = dep.getData( ) }
class Repository ( private val dep: Dependenc y ) {
fun fetch() = dep.getData( ) }
What should I test?
Test the logic, not the code. Fabio Collini (probably?)
fun testCode() { repository.fetch( ) verify(mockDependency).getData( ) }
fun testLogic() { val actualResult = repository.fetch( ) verify(actualResult )
.isEqualTo(expectedResult ) }
Was that unit testing?
Was that unit testing? Is unit testing enough?
cwti.link/twitch
What about integration testing?
What about integration testing? integration tests validate the collaboration and
interaction of a group of units.
My take on integration testing
My take on integration testing •No Android deps •Test fl
ow from start to end •Use Robolectric
class RootFragment : Fragment() { lateinit var repository: Repositor y
lateinit var view: Vie w fun onResume() { val response = repository.fetchThings( ) view.bindResults(response ) } }
class IntegrationTest { private val mock = TestDouble(Service() ) private
val testFragment = RootFragment( ) fun integrationTest() { run(testFragment).verify( ) } } androidTest
What about Network?
What about network? Network is unreliable
What about network? • Retro fi t + OkHttp +
MockWebServer • Ktor + MockEngine
val retrofit = Retrofit.Builder( ) .baseUrl("https://api.github.com/" ) .build( ) This
should come from the outside!
val retrofit = Retrofit.Builder( ) .baseUrl(url ) .build( )
val server = MockWebServer( ) server.enqueue ( MockResponse().setBody("hello, world!" )
) server.start( ) val url = server.url( )
HttpClient(Android) { install(Logging) { … } install(JsonFeature) { … }
} This should come from the outside!
val mockEngine = MockEngine { request - > respond (
content = ByteReadChannel(content) , status = HttpStatusCode.OK , headers = headersOf(ContentType, type ) ) }
What about UI testing?
What about UI testing?
@get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>( ) @Tes t fun changeText()
{ onView(withId(startViewId) ) .perform ( typeText(MESSAGE) , closeSoftKeyboard( ) ) onView(withId(buttonViewId) ) .perform(click() ) onView(withId(targetView) ) .check(matches(withText(MESSAGE)) ) }
None
None
@Composabl e fun SimpleUI() { var clicks by remember {
mutableStateOf(0) } Column { Button ( onClick = { clicks++ } ) { Text(text = "Click me" ) } if (clicks > 0) { Text(text = "$clicks" ) } } }
@get:Rul e val composeTestRule = createComposeRule( ) @Tes t fun
verify_initial_case() { composeTestRule.setContent { SimpleUI( ) } composeTestRule.onNodeWithTag("clicks" ) .assertDoesNotExist( ) }
@get:Rul e val composeTestRule = createComposeRule( ) @Tes t fun
verify_last_case() { composeTestRule.setContent { SimpleUI( ) } composeTestRule.onNodeWithText("Click me" ) .performClick( ) with(composeTestRule.onNodeWithTag("clicks")) { assertIsDisplayed( ) assertTextEquals("1" ) } }
How can I start testing?
Roberto Orgiu | Senior Android Engineer @ NYTimes | @_tiwiz
Thanks for listening. Q&A Time