Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
One way to organize UI tests (with Robots)
Search
Daniel
September 06, 2017
Programming
96
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
One way to organize UI tests (with Robots)
Slides for meetup:
https://www.meetup.com/es-ES/Medellin-Android/events/242937374/
Daniel
September 06, 2017
More Decks by Daniel
See All by Daniel
Dependency Inversion from S to D (SOLID)
danielgomezrico
0
43
Dependency Injection
danielgomezrico
0
78
Test Robots
danielgomezrico
0
71
(kotlin + patterns ) _ ui-test = happy developer DROIDS4DROIDS
danielgomezrico
0
51
(kotlin + patterns) * ui-tests = happy developer
danielgomezrico
0
58
(Android|iOS) + gitlab ci
danielgomezrico
0
140
Lets talk in / Dilo en Kotlin
danielgomezrico
0
96
Pimp my android project
danielgomezrico
1
76
WTF is origin
danielgomezrico
0
81
Other Decks in Programming
See All in Programming
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
560
テーブルをDELETEした
yuzneri
0
120
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
230
その節約、円になってますか?
isamumumu
0
490
壊れたパーサから始める関数型設計と構成的なパーサ #fp_matsuri
raiga0310
2
420
AI時代のPHPer生存戦略 ~「言語、もうなんでもよくない?」に本気で向き合う~
vivion
0
210
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
0
170
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
2.7k
What's New in Android 2026
veronikapj
0
240
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
190
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
300
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.3k
Featured
See All Featured
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Color Theory Basics | Prateek | Gurzu
gurzu
0
400
The SEO identity crisis: Don't let AI make you average
varn
0
520
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.3k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
ラッコキーワード サービス紹介資料
rakko
1
4.1M
Into the Great Unknown - MozCon
thekraken
41
2.6k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
67
56k
Rails Girls Zürich Keynote
gr2m
96
14k
GitHub's CSS Performance
jonrohan
1033
470k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
330
Transcript
A way to organize UI tests Daniel Gomez Rico Android
Lead Developer at Barista Ventures @aquicaipivara With UI Robots…
1. Login Example app 2. Main
Tests UI / otro Framework Tests without robots
@Test fun test_login_showMainView() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText("
[email protected]
"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText("12345678"),
ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withText("Login")) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) } Without robots
Tests UI Or another Framework Tests without robots
Tests UI Tests with robots… UI Robots
@Test fun test_login_showMainView() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText("
[email protected]
"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText("12345678"),
ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)) .perform(ViewActions.click()) Espresso.onView(ViewMatchers.withText("Login")) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) } Without robot Sample 1/3
@Test fun test_login_showMainView() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText("
[email protected]
"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText(“007"),
ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)) .perform(ViewActions.click()) Espresso.onView(ViewMatchers.withText(“Main")) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) } MainRobot Looks like actions from a Login View -> LoginRobot
class LoginTests { @Test fun test_login_showMainView() { val mainRobot =
loginRobot.writeEmail("
[email protected]
") .writePassword(“007") .clickLoginButton() // Returns MainRobot mainRobot.checkIsVisible() } } With robots… Sample 1/3
class MainTests { @Test fun test_onLogout_showLoginView() { val mainRobot
= loginRobot.performLoginFlow() //return MainRobot mainRobot.clickLogoutButton() loginRobot.checkIsVisible() } } With robots… Sample 2/3
class LoginTestsWithoutRobot { @Test fun test_login_showMainView() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText("
[email protected]
"),
ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText("12345678"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withText("Login")) .check(ViewAssertions.matches(ViewMatchers.isDisplayed())) } @Test fun test_login_withEmptyEmail_showsError() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText(""), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText("12345678"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .check(ViewAssertions.matches(CustomMatchers.withError())) } @Test fun test_login_withEmptyPassword_showsError() { Espresso.onView(ViewMatchers.withId(R.id.loginUsernameEditText)) .perform(ViewActions.typeText("
[email protected]
"), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .perform(ViewActions.typeText(""), ViewActions.closeSoftKeyboard()) Espresso.onView(ViewMatchers.withId(R.id.loginSubmitButton)).perform(ViewActions.click()) Espresso.onView(ViewMatchers.withId(R.id.loginPasswordEditText)) .check(ViewAssertions.matches(CustomMatchers.withError())) } } Without robot Sample 3/3
@Test fun test_login_showMainView() { val mainRobot = loginRobot.writeEmail("
[email protected]
") .writePassword("007") .clickLoginButton()
// Returns MainRobot mainRobot.checkIsVisible() } @Test fun test_login_withEmptyEmail_showsError() { loginRobot.writeEmail("") .writePassword("123") .clickLoginButton() loginRobot.checkEmailHaveError() } @Test fun test_login_withEmptyPassword_showsError() { loginRobot.writeEmail("
[email protected]
") .writePassword("") .clickLoginButton() loginRobot.checkPasswordHaveError() } With robots… Sample 3/3
class NewQuestionActivityTest { @Test fun newQuestionTest() { val mainRobot
= onBoardingRobot.clickLoginButton() .performLoginFlow() val newQuestionRobot = mainRobot.clickNewQuestionFab() val creditCardRobot = newQuestionRobot.writeDescription(getRandomQuestion()) .selectSubtopic(0) .selectExpert(0) .clickSubmitButton() .clickRushPaymentOption() .clickOkButton() val mainRobot = creditCardRobot.performSuccessFlow() mainRobot.validateIsVisible() } } With robots… “Big” test
fun selectSubtopic(index: Int) { click(R.id.newQuestionSubtopicsEditText) clickListItemDialogItem(index) } fun click(@IdRes id:
Int) { onView(withId(id)).perform(ViewActions.click()) } private fun clickListItemDialogItem(index: Int) { val action = RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>(index, ViewActions.click()) Espresso.onView(ViewMatchers.withId(R.id.checkDialogRecyclerView)).perform(action) clickViewWithText("OK") } protected fun clickViewWithText(text: String) { screenshot("before_click") onView(allOf<View>(withText(text), isDisplayed())).perform(ViewActions.click()) screenshot("click") }
The UI Robot Sample project https://github.com/caipivara/androidmeetup-ui-robots Check
- https://academy.realm.io/posts/kau-jake-wharton-testing-robots/ - Android Dialogs (Sam Edwards: Espresso Robots +
Screenshots): https://www.youtube.com/watch?v=vsrX0gGZp3o - Sample: https://github.com/caipivara/androidmeetup-ui-robots - Icons: https://www.iconfinder.com/icons/58995/ lionel_preacherbot_robot_icon References
Gracias!!