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
94
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
41
Dependency Injection
danielgomezrico
0
77
Test Robots
danielgomezrico
0
69
(kotlin + patterns ) _ ui-test = happy developer DROIDS4DROIDS
danielgomezrico
0
50
(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
フロントエンドとバックエンドで「1文字」を揃えよう
youkidearitai
PRO
0
750
不変条件と整合性境界—ビジネスが決める設計判断と実現パターン / Invariants and Consistency Boundaries
nrslib
14
5.9k
そのテスト、説明できますか?~LWテスト戦略FW~のご紹介
nakahara
0
170
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
1
500
エージェンティックRAGにAWSで入門しよう!
har1101
9
1.8k
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
210
Lessons from Spec-Driven Development
simas
PRO
0
220
どこまでゆるくて許されるのか
tk3fftk
0
260
Datadog LLM Observabilityで実現する 安全なLLM Usage 管理
3150
0
120
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
15
7.5k
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
310
act1-costs.pdf
sumedhbala
0
120
Featured
See All Featured
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.5k
A better future with KSS
kneath
240
18k
30 Presentation Tips
portentint
PRO
1
330
YesSQL, Process and Tooling at Scale
rocio
174
15k
The agentic SEO stack - context over prompts
schlessera
0
830
The SEO Collaboration Effect
kristinabergwall1
1
490
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
190
B2B Lead Gen: Tactics, Traps & Triumph
marketingsoph
0
160
Skip the Path - Find Your Career Trail
mkilby
1
150
Joys of Absence: A Defence of Solitary Play
codingconduct
1
400
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!!