SlideShare uma empresa Scribd logo
1 de 34
Testing
Android Apps
with Espresso
About me
Édipo Souza
Édipo Souza has over 3 years experience in android development with
Degree in Sistemas e Mídias Digitais by Federal University of Ceará (UFC)
and Specialization in Desenvolvimento de Sistemas para Dispositivos Móveis
by Faculdade Sete de Setembro (FA7).
He has certifications Oracle Certified Associate Java SE 8 Programmer and
Programming in HTML5 with JavaScript and CSS3 Specialist.
● What’s Espresso?
● Why use Espresso?
● Configuration
● Android Test Rules
● Main Components
● Espresso Cheat Sheet
● JUnit Annotations
● Extra Libraries
○ Espresso-Contrib
○ Espresso-Intents
○ UI Automator
● Development Tips
● Commun Situations and Solution
Schedule
● “A simple API for writing reliable UI tests” - Google
● Backward Compatibility Api 8 (Froyo) or Higher
● Open Source - https://code.google.com/p/android-test-kit
● Google Product - Presented at Google Test Automation Conference 2013
● Android Tool - Added to Android Testing Support Library in 2015 with
Version 2.1 released on 2015/04/21
● Actual version 2.2
What’s Espresso?
● “The core API is small, predictable, and easy to learn and yet remains
open for customization” - Google
● Easy - “An extensive set of action APIs to automate UI interactions.”
● Extensible - “Flexible APIs for view and adapter matching in target apps.”
● Fast - “UI thread synchronization to improve test reliability.”
● No WaitFor(), No Sleep()!
● JUnit4 Support.
Why use Espresso?
● Add these lines in your biuld.gradle file
Configuration
defaultConfig {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
packagingOptions {
exclude 'NOTICE.txt'
exclude 'LICENSE.txt'
}
● Add these dependencies in your biuld.gradle file
Configuration
dependencies {
androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2'){exclude
module: 'support-annotations'}
androidTestCompile ('com.android.support.test.espresso:espresso-intents:2.2'){exclude
module: 'support-annotations'}
androidTestCompile ('com.android.support.test:runner:0.3'){exclude module: 'support-
annotations'}
androidTestCompile ('com.android.support.test:rules:0.3'){exclude module: 'support-
annotations'}
//Optional for uiAutomator
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1'
//Optional for RecyclerView
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2') {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'support-annotations'
exclude module: 'recyclerview-v7'
}
}
● Make use of JUnit4 @Rule annotation
● Extends ActivityInstrumentationTestCase2 or ServiceTestCase are
deprecated
● ActivityTestRule
The activity under the Rule will be launched again in each Test
@Rule
public ActivityTestRule<MyActivity> activityRule = new ActivityTestRule<>(MyActivity.class);
● ServiceTestRule
The service will start and shutdown in each Test using startService it method
@Rule
public final ServiceTestRule mServiceRule = new ServiceTestRule();
Android Test Rules
OK, show me Code!
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Rule
public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);
@Test
public void testClickOKButtonAnd() {
}
}
Main Components
Matcher - Provide a way to find a view instance on
view hierarchy that matches a given criteria.
ViewAction - Provide instructions
to perform an Action
on view object.
ViewAssertion - Allows to check if some
view object state matches
with given criteria. This
can make the Test fail.
ViewMatcher
Matcher Categories
● User Properties
Commun component attributes
● UI Properties
Commun UI component state
● Object
Group, Logic and Text helpers
● Hierarchy
Identifiers based on relationship
● Input
Type support
● Class
Identifiers based on object class
● Root
Window holding view object
Let’s see it on Code!
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Rule
public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);
@Test
public void testClickOKButtonAnd() {
//Find a button with text 'play'
onView(withText(R.string.play))
}
}
Action Categories
● Click/Press
Commun tap actions
● Gestures
Swipe and Scroll actions
● Text
Editable actions
ViewActions
Cool, but and the Code?
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Rule
public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);
@Test
public void testClickOKButtonAnd() {
//Click on button with text 'play'
onView(withText(R.string.play)).perform(click())
}
}
Assertions Categories
● Generic
Helpers assertions
● Layout
Overlay relationship
● Positions
View positions relationship
ViewAssertions
OK, but I want see Code!
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Rule
public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class);
@Test
public void testClickOKButtonAnd() {
//Click on button with text 'play' and Check if text change to 'stop'
onView(withText(R.string.play)).perform(click()).check(matches(withText(R.string.stop)));
}
}
//Click on button with text 'play'. Check if view with id btPlayStop has text 'stop'
onView(withText(R.string.play)).perform(click());
onView(withId(R.id.btPlayStop)).check(matches(withText(R.string.stop)));
//Click on item with text 'Track 3’ in a list of strings.
onData(allOf(is(instanceOf(String.class)), is("Track 3"))).perform(click());
Espresso Cheat Sheet
Junit Annotations
@BeforeClass
The method is executed
before all test methods
@Before
This method is executed
before each test method
@AfterClass
This method is executed
after all test methods
@After
This method is
executed after each test
method
@BeforeClass
public static void setUp() {
...
}
@Before
public static void setupForEachTest() {
...
}
@Test
public void test1() {
...
}
@Test
public void test2() {
…
}
@After
public static void undoSetupForEachTest() {
…
}
@AfterClass
public static void undoSetup() {
…
}
● Espresso-Contrib
Contains Actions to RecyclerView and system components like Pickers
● Espresso-Intents
Allows to Check or Mock response of started intents
● Espresso-Idling-Resource
Enable to define new resources to Espresso wait before proceed
● UI Automator
Let you do BlackBox test actions on system and third party apps
Extra Libraries
DrawerActions
○ openDrawer(int drawerLayoutId)
○ closeDrawer(int drawerLayoutId)
Espresso-Contrib
DrawerMatches
○ isOpen()
○ isClosed()
RecyclerViewActions
Needed because recyclerView extends ViewGroup, not AdapterView, so no onData for
it.
Espresso-Contrib
Actions
○ actionOnHolderItem(Matcher<VH> viewHolderMatcher, ViewAction viewAction)
○ actionOnItem(Matcher<View> itemViewMatcher, ViewAction viewAction)
○ actionOnItemAtPosition(int position, ViewAction viewAction)
Scroll
○ scrollTo(Matcher<View> itemViewMatcher)
○ scrollToHolder(Matcher<VH> viewHolderMatcher)
○ scrollToPosition(int position)
PickerActions
Needed for interact with DatePicker and TimerPicker
Espresso-Contrib
TimePicker
○ setTime(int hours, int minutes)
DatePicker
○ setDate(int year, int monthOfYear, int dayOfMonth)
❖ intended(intentMatcher)
Allows validation of Intents sent out
by the application under test.
Espresso-Intents
❖ intending(intentMatcher)
.respondWith(activityResult)
Enables stubbing the response of
Intents sent by startActivityForResult
“It’s like Mockito, but for android intents.”
Matcher Categories
● Intent
Commun intent parameters
● URI
URI attributes validations
● Component Name
Component class and package validations
● Bundle
Search intent based on Entry, Key or
Value
“ UI Automator is well-suited for writing black box-style automated tests”
UI Automator
UIDevice UISelector
○ findObject(UiSelector selector)
○ findObjects(BySelector selector)
○ takeScreenshot(File storePath)
○ pressHome() / Back / Menu / RecentApps
○ pressEnder() / Search / KeyCode(int keyCode)
○ click(int x, int y)
○ swipe(int initX, int initY, int endX, int endY, int steps)
○ openNotification()
○ openQuickSettings()
○ setOrientationLeft() / Right() / Natural()
○ sleep() / wakeUp() / isScreenOn()
○ checked(boolean val)
○ focusable(boolean val)
○ className(Class<T> type)
○ description(String desc)
○ resourceId(String id)
○ text(String text)
○ click() / AndWaitForNewWindow()
○ exists()
○ getText() / setText(String text) /
clearTextField()
○ swipeUp(int steps) Down/Left/Right
UIObject
Cool, I want see it on Code!
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiSelector;
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
@Test
public void openMemoAndAddANewNote() throws Exception {
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
}
}
//Go to launcher home
uiDevice.pressHome();
//click apps button to open apps drawer
uiDevice.findObject(new UiSelector().description("Apps")).clickAndWaitForNewWindow();
//open calculator
uiDevice.findObject(new UiSelector().text("Calculator")).clickAndWaitForNewWindow();
//Calculate 3*9
uiDevice.findObject(new UiSelector().description("3")).click();
uiDevice.findObject(new UiSelector().description("Multiply")).click();
uiDevice.findObject(new UiSelector().description("9")).click();
uiDevice.findObject(new UiSelector().description("equal")).click();
//create a selector for result display text based on its resourceId
UiSelector resultSelector = new UiSelector().resourceId("com.android.calculator2:id/display_Res_Text");
//check result
assertEquals("equal 27", uiDevice.findObject(resultSelector).getText());
“ UI Automator is well-suited for writing black box-style automated tests”
UI Automator Viewer
DEMO
I want Espresso in Action!
● Get the application context
● Get the test application context
● Obtain the context of activity to be tested
● The withText() method can be used with a string resource id
Development Tips
InstrumentationRegistry.getTargetContext();
Test class
activityRule.getActivity().getApplicationContext();
Activity
InstrumentationRegistry.getContext();
@Rule
public ActivityTestRule<MyActivity> activityRule = new ActivityTestRule<>(MyActivity.class);
activityRule.getActivity().getContext();
withText(R.string.test)
● When is expected that the test returns an exception, simply add the
expected exception to Test annotation:
● However for large testing is recommended to use use ExpectedException
Rule
Development Tips
@Test(expected = IndexOutOfBoundsException.class)
public void test1() {
}
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
list.get(0); // execution will never get past this line
}
● To interact with the items from Spinner, PopupMenu or similar use:
'.inRoot(isPlatformPopup())'
● Stay tuned when performs swipe in a pageView to find an item in list.
Perform a click in a tab for that the items can be found
Commun Situations/Solution
//Clicks in spinner
onView(withId(R.id.spinnerCountries)).perform(click());
//Select the country Brazil and clicks in it
onData(allOf(is(instanceOf(String.class)), is(“Brazil”))).inRoot(isPlatformPopup()).perform(click());
//Click TAB1
onView(withText(“TAB1”)).perform(click());
● As RecyclerView extends ViewGroup should be used the onView
method to find items in list instead of onData
● If a RecyclerView item is not visible, unlike the ListView, a scroll must be
made to the item using RecyclerViewActions.scrollTo() before interacting
with the item.
Commun Situations/Solution
// Perform a click on first element in the RecyclerView
onView(withId(R.id.recyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
Object rvTag = 0;
Matcher<View> viewMatcher = hasDescendant(withText(“Item 100”));
onView(withTagValue(is(rvTag))).perform(RecyclerViewActions.scrollTo(viewMatcher));
● To check whether a toast was displayed
● To perform an action conditionally, we can override the method
withFailureHandler, then if the check fails, instead of finishing the test,
the method handle is called
Commun Situations/Solution
//Get the decorView
View activityDecorView = mActivityRule.getActivity().getWindow().getDecorView();
onView(withText(TOAST_TEXT)).inRoot(withDecorView(not(activityDecorView))).check(isDisplayed());
onView(withText(R.string.dialog_config_app)).withFailureHandler(new FailureHandler() {
@Override
public void handle(Throwable throwable, Matcher<View> matcher) {
onView(withText(android.R.string.ok)).perform(click());
}
}).check(doesNotExist());
Cool Links:
● https://code.google.com/p/android-test-kit/
● https://github.com/vgrec/EspressoExamples/
● http://www.vogella.com/tutorials/Mockito/article.html
● https://github.com/junit-team/junit/wiki/Exception-testing
● https://developer.android.com/tools/testing-support-library/index.html
● https://github.com/googlesamples/android-testing/tree/master/espresso
● https://androidresearch.wordpress.com/2015/04/04/an-introduction-to-espresso
Questions?
Contact
edipo2s@gmail.com
www.ediposouza.com
THANKS!!!

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Unit tests & TDD
Unit tests & TDDUnit tests & TDD
Unit tests & TDD
 
Cypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdfCypress Automation Testing Tutorial (Part 1).pdf
Cypress Automation Testing Tutorial (Part 1).pdf
 
Unit Testing with Jest
Unit Testing with JestUnit Testing with Jest
Unit Testing with Jest
 
Angular Unit Testing
Angular Unit TestingAngular Unit Testing
Angular Unit Testing
 
Effective Software Test Case Design Approach
Effective Software Test Case Design ApproachEffective Software Test Case Design Approach
Effective Software Test Case Design Approach
 
Como criar testes rápidos e robustos com Cypress
Como criar testes rápidos e robustos com CypressComo criar testes rápidos e robustos com Cypress
Como criar testes rápidos e robustos com Cypress
 
Testing of React JS app
Testing of React JS appTesting of React JS app
Testing of React JS app
 
Unit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and KarmaUnit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and Karma
 
Appium Presentation
Appium Presentation Appium Presentation
Appium Presentation
 
Automated testing with Cypress
Automated testing with CypressAutomated testing with Cypress
Automated testing with Cypress
 
Cypress e2e automation testing - day1 intor by: Hassan Hameed
Cypress e2e automation testing -  day1 intor by: Hassan HameedCypress e2e automation testing -  day1 intor by: Hassan Hameed
Cypress e2e automation testing - day1 intor by: Hassan Hameed
 
Writing and using Hamcrest Matchers
Writing and using Hamcrest MatchersWriting and using Hamcrest Matchers
Writing and using Hamcrest Matchers
 
How to go about testing in React?
How to go about testing in React? How to go about testing in React?
How to go about testing in React?
 
What is JUnit? | Edureka
What is JUnit? | EdurekaWhat is JUnit? | Edureka
What is JUnit? | Edureka
 
Bdd with Cucumber and Mocha
Bdd with Cucumber and MochaBdd with Cucumber and Mocha
Bdd with Cucumber and Mocha
 
Agile Testing and Test Automation
Agile Testing and Test AutomationAgile Testing and Test Automation
Agile Testing and Test Automation
 
Cucumber BDD
Cucumber BDDCucumber BDD
Cucumber BDD
 
How to Get Started with Cypress
How to Get Started with CypressHow to Get Started with Cypress
How to Get Started with Cypress
 
Getting Started with XCTest and XCUITest for iOS App Testing
Getting Started with XCTest and XCUITest for iOS App TestingGetting Started with XCTest and XCUITest for iOS App Testing
Getting Started with XCTest and XCUITest for iOS App Testing
 
Appium
AppiumAppium
Appium
 

Destaque

Destaque (20)

Ui testing with espresso
Ui testing with espressoUi testing with espresso
Ui testing with espresso
 
Continous UI testing with Espresso and Jenkins
Continous UI testing with Espresso and JenkinsContinous UI testing with Espresso and Jenkins
Continous UI testing with Espresso and Jenkins
 
Android Espresso
Android EspressoAndroid Espresso
Android Espresso
 
JUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit TestsJUnit Kung Fu: Getting More Out of Your Unit Tests
JUnit Kung Fu: Getting More Out of Your Unit Tests
 
Automated android testing using jenkins ci
Automated android testing using jenkins ciAutomated android testing using jenkins ci
Automated android testing using jenkins ci
 
Do You Enjoy Espresso in Android App Testing?
Do You Enjoy Espresso in Android App Testing?Do You Enjoy Espresso in Android App Testing?
Do You Enjoy Espresso in Android App Testing?
 
Espresso Presentation FINAL
Espresso Presentation FINALEspresso Presentation FINAL
Espresso Presentation FINAL
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
 
Espresso introduction
Espresso introductionEspresso introduction
Espresso introduction
 
An Introduction to RxJava
An Introduction to RxJavaAn Introduction to RxJava
An Introduction to RxJava
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to RxStreams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
 
Utilizando Espresso e UIAutomator no Teste de Apps Android
Utilizando Espresso e UIAutomator no Teste de Apps AndroidUtilizando Espresso e UIAutomator no Teste de Apps Android
Utilizando Espresso e UIAutomator no Teste de Apps Android
 
Fast deterministic screenshot tests for Android
Fast deterministic screenshot tests for AndroidFast deterministic screenshot tests for Android
Fast deterministic screenshot tests for Android
 
Mobile applications and automation testing
Mobile applications and automation testingMobile applications and automation testing
Mobile applications and automation testing
 
Tech Talk #5 : Android Automation Test with Espresso - Trần Văn Toàn
Tech Talk #5 : Android Automation Test with Espresso - Trần Văn ToànTech Talk #5 : Android Automation Test with Espresso - Trần Văn Toàn
Tech Talk #5 : Android Automation Test with Espresso - Trần Văn Toàn
 
Ewa Bielska: Testowanie aplikacji mobilnych
Ewa Bielska: Testowanie aplikacji mobilnychEwa Bielska: Testowanie aplikacji mobilnych
Ewa Bielska: Testowanie aplikacji mobilnych
 
Androidテスティング実践2 システムテスト編
Androidテスティング実践2 システムテスト編Androidテスティング実践2 システムテスト編
Androidテスティング実践2 システムテスト編
 
Automated UI Testing Frameworks
Automated UI Testing FrameworksAutomated UI Testing Frameworks
Automated UI Testing Frameworks
 
Genymotion with Jenkins
Genymotion with JenkinsGenymotion with Jenkins
Genymotion with Jenkins
 
Packaging Your Story: Social Media for B2Bs
Packaging Your Story: Social Media for B2BsPackaging Your Story: Social Media for B2Bs
Packaging Your Story: Social Media for B2Bs
 

Semelhante a Testing android apps with espresso

Adding custom ui controls to your application (1)
Adding custom ui controls to your application (1)Adding custom ui controls to your application (1)
Adding custom ui controls to your application (1)
Oro Inc.
 

Semelhante a Testing android apps with espresso (20)

Espresso
EspressoEspresso
Espresso
 
Advanced Dagger talk from 360andev
Advanced Dagger talk from 360andevAdvanced Dagger talk from 360andev
Advanced Dagger talk from 360andev
 
Getting started with appium
Getting started with appiumGetting started with appium
Getting started with appium
 
Overview the Challenges and Limitations of Android App Automation with Espres...
Overview the Challenges and Limitations of Android App Automation with Espres...Overview the Challenges and Limitations of Android App Automation with Espres...
Overview the Challenges and Limitations of Android App Automation with Espres...
 
Android Test Automation Workshop
Android Test Automation WorkshopAndroid Test Automation Workshop
Android Test Automation Workshop
 
Dive into Angular, part 5: Experience
Dive into Angular, part 5: ExperienceDive into Angular, part 5: Experience
Dive into Angular, part 5: Experience
 
Browser_Stack_Intro
Browser_Stack_IntroBrowser_Stack_Intro
Browser_Stack_Intro
 
Adding custom ui controls to your application (1)
Adding custom ui controls to your application (1)Adding custom ui controls to your application (1)
Adding custom ui controls to your application (1)
 
UIAutomator
UIAutomatorUIAutomator
UIAutomator
 
Android the Agile way
Android the Agile wayAndroid the Agile way
Android the Agile way
 
Android Support Library: Using ActionBarCompat
Android Support Library: Using ActionBarCompatAndroid Support Library: Using ActionBarCompat
Android Support Library: Using ActionBarCompat
 
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex ScenariosUnit Testing in Flutter - From Workflow Essentials to Complex Scenarios
Unit Testing in Flutter - From Workflow Essentials to Complex Scenarios
 
Android testing part i
Android testing part iAndroid testing part i
Android testing part i
 
Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016
Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016
Dusan Lukic Magento 2 Integration Tests Meet Magento Serbia 2016
 
A journey through android development
A journey through android developmentA journey through android development
A journey through android development
 
Code igniter unittest-part1
Code igniter unittest-part1Code igniter unittest-part1
Code igniter unittest-part1
 
Good practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium testsGood practices for debugging Selenium and Appium tests
Good practices for debugging Selenium and Appium tests
 
Utilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps androidUtilizando expresso uiautomator na automacao de testes em apps android
Utilizando expresso uiautomator na automacao de testes em apps android
 
Unit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdfUnit Testing Using Mockito in Android (1).pdf
Unit Testing Using Mockito in Android (1).pdf
 
Innovation Generation - The Mobile Meetup: Android Best Practices
Innovation Generation - The Mobile Meetup: Android Best PracticesInnovation Generation - The Mobile Meetup: Android Best Practices
Innovation Generation - The Mobile Meetup: Android Best Practices
 

Mais de Édipo Souza

Framework MVC - vRaptor
Framework MVC - vRaptorFramework MVC - vRaptor
Framework MVC - vRaptor
Édipo Souza
 
XP - eXtreme Programming
XP - eXtreme ProgrammingXP - eXtreme Programming
XP - eXtreme Programming
Édipo Souza
 

Mais de Édipo Souza (13)

Estudo comparativo das linguagens kotlin e java no desenvolvimento de aplicac...
Estudo comparativo das linguagens kotlin e java no desenvolvimento de aplicac...Estudo comparativo das linguagens kotlin e java no desenvolvimento de aplicac...
Estudo comparativo das linguagens kotlin e java no desenvolvimento de aplicac...
 
Android, Gradle & Dependecies
Android, Gradle & DependeciesAndroid, Gradle & Dependecies
Android, Gradle & Dependecies
 
Android studio build variants
Android studio build variantsAndroid studio build variants
Android studio build variants
 
Next Step, Android Studio!
Next Step, Android Studio!Next Step, Android Studio!
Next Step, Android Studio!
 
Introdução a Plataforma Android
Introdução a Plataforma AndroidIntrodução a Plataforma Android
Introdução a Plataforma Android
 
Apresentação de minha Monografia do curso de Sistema e Mídias Digitais
Apresentação de minha Monografia do curso de Sistema e Mídias DigitaisApresentação de minha Monografia do curso de Sistema e Mídias Digitais
Apresentação de minha Monografia do curso de Sistema e Mídias Digitais
 
UMA ANÁLISE COMPARATIVA DE FERRAMENTAS DE DESENVOLVIMENTO MULTIPLATAFORMA PAR...
UMA ANÁLISE COMPARATIVA DE FERRAMENTAS DE DESENVOLVIMENTO MULTIPLATAFORMA PAR...UMA ANÁLISE COMPARATIVA DE FERRAMENTAS DE DESENVOLVIMENTO MULTIPLATAFORMA PAR...
UMA ANÁLISE COMPARATIVA DE FERRAMENTAS DE DESENVOLVIMENTO MULTIPLATAFORMA PAR...
 
Android - Frameworks de Testes
Android - Frameworks de TestesAndroid - Frameworks de Testes
Android - Frameworks de Testes
 
Android - Frameworks para Gráficos
Android - Frameworks para GráficosAndroid - Frameworks para Gráficos
Android - Frameworks para Gráficos
 
Logging Patterns & Anti-Patterns
Logging Patterns & Anti-PatternsLogging Patterns & Anti-Patterns
Logging Patterns & Anti-Patterns
 
Android - Frameworks de Persistência
Android - Frameworks de PersistênciaAndroid - Frameworks de Persistência
Android - Frameworks de Persistência
 
Framework MVC - vRaptor
Framework MVC - vRaptorFramework MVC - vRaptor
Framework MVC - vRaptor
 
XP - eXtreme Programming
XP - eXtreme ProgrammingXP - eXtreme Programming
XP - eXtreme Programming
 

Último

Chiulli_Aurora_Oman_Raffaele_Beowulf.pptx
Chiulli_Aurora_Oman_Raffaele_Beowulf.pptxChiulli_Aurora_Oman_Raffaele_Beowulf.pptx
Chiulli_Aurora_Oman_Raffaele_Beowulf.pptx
raffaeleoman
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
David Celestin
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
amilabibi1
 
If this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New NigeriaIf this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New Nigeria
Kayode Fayemi
 
Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
Kayode Fayemi
 

Último (15)

Chiulli_Aurora_Oman_Raffaele_Beowulf.pptx
Chiulli_Aurora_Oman_Raffaele_Beowulf.pptxChiulli_Aurora_Oman_Raffaele_Beowulf.pptx
Chiulli_Aurora_Oman_Raffaele_Beowulf.pptx
 
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
Proofreading- Basics to Artificial Intelligence Integration - Presentation:Sl...
 
Report Writing Webinar Training
Report Writing Webinar TrainingReport Writing Webinar Training
Report Writing Webinar Training
 
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdfSOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
SOLID WASTE MANAGEMENT SYSTEM OF FENI PAURASHAVA, BANGLADESH.pdf
 
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
Bring back lost lover in USA, Canada ,Uk ,Australia ,London Lost Love Spell C...
 
If this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New NigeriaIf this Giant Must Walk: A Manifesto for a New Nigeria
If this Giant Must Walk: A Manifesto for a New Nigeria
 
Dreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video TreatmentDreaming Marissa Sánchez Music Video Treatment
Dreaming Marissa Sánchez Music Video Treatment
 
Digital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of DrupalDigital collaboration with Microsoft 365 as extension of Drupal
Digital collaboration with Microsoft 365 as extension of Drupal
 
ICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdfICT role in 21st century education and it's challenges.pdf
ICT role in 21st century education and it's challenges.pdf
 
Dreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio IIIDreaming Music Video Treatment _ Project & Portfolio III
Dreaming Music Video Treatment _ Project & Portfolio III
 
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdfAWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
AWS Data Engineer Associate (DEA-C01) Exam Dumps 2024.pdf
 
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdfThe workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
The workplace ecosystem of the future 24.4.2024 Fabritius_share ii.pdf
 
lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.lONG QUESTION ANSWER PAKISTAN STUDIES10.
lONG QUESTION ANSWER PAKISTAN STUDIES10.
 
Uncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac FolorunsoUncommon Grace The Autobiography of Isaac Folorunso
Uncommon Grace The Autobiography of Isaac Folorunso
 
My Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle BaileyMy Presentation "In Your Hands" by Halle Bailey
My Presentation "In Your Hands" by Halle Bailey
 

Testing android apps with espresso

  • 2. About me Édipo Souza Édipo Souza has over 3 years experience in android development with Degree in Sistemas e Mídias Digitais by Federal University of Ceará (UFC) and Specialization in Desenvolvimento de Sistemas para Dispositivos Móveis by Faculdade Sete de Setembro (FA7). He has certifications Oracle Certified Associate Java SE 8 Programmer and Programming in HTML5 with JavaScript and CSS3 Specialist.
  • 3. ● What’s Espresso? ● Why use Espresso? ● Configuration ● Android Test Rules ● Main Components ● Espresso Cheat Sheet ● JUnit Annotations ● Extra Libraries ○ Espresso-Contrib ○ Espresso-Intents ○ UI Automator ● Development Tips ● Commun Situations and Solution Schedule
  • 4. ● “A simple API for writing reliable UI tests” - Google ● Backward Compatibility Api 8 (Froyo) or Higher ● Open Source - https://code.google.com/p/android-test-kit ● Google Product - Presented at Google Test Automation Conference 2013 ● Android Tool - Added to Android Testing Support Library in 2015 with Version 2.1 released on 2015/04/21 ● Actual version 2.2 What’s Espresso?
  • 5. ● “The core API is small, predictable, and easy to learn and yet remains open for customization” - Google ● Easy - “An extensive set of action APIs to automate UI interactions.” ● Extensible - “Flexible APIs for view and adapter matching in target apps.” ● Fast - “UI thread synchronization to improve test reliability.” ● No WaitFor(), No Sleep()! ● JUnit4 Support. Why use Espresso?
  • 6. ● Add these lines in your biuld.gradle file Configuration defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } packagingOptions { exclude 'NOTICE.txt' exclude 'LICENSE.txt' }
  • 7. ● Add these dependencies in your biuld.gradle file Configuration dependencies { androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2'){exclude module: 'support-annotations'} androidTestCompile ('com.android.support.test.espresso:espresso-intents:2.2'){exclude module: 'support-annotations'} androidTestCompile ('com.android.support.test:runner:0.3'){exclude module: 'support- annotations'} androidTestCompile ('com.android.support.test:rules:0.3'){exclude module: 'support- annotations'} //Optional for uiAutomator androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.1' //Optional for RecyclerView androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2') { exclude group: 'com.android.support', module: 'appcompat' exclude group: 'com.android.support', module: 'support-v4' exclude module: 'support-annotations' exclude module: 'recyclerview-v7' } }
  • 8. ● Make use of JUnit4 @Rule annotation ● Extends ActivityInstrumentationTestCase2 or ServiceTestCase are deprecated ● ActivityTestRule The activity under the Rule will be launched again in each Test @Rule public ActivityTestRule<MyActivity> activityRule = new ActivityTestRule<>(MyActivity.class); ● ServiceTestRule The service will start and shutdown in each Test using startService it method @Rule public final ServiceTestRule mServiceRule = new ServiceTestRule(); Android Test Rules
  • 9. OK, show me Code! import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) public class MyActivityTest { @Rule public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class); @Test public void testClickOKButtonAnd() { } }
  • 10. Main Components Matcher - Provide a way to find a view instance on view hierarchy that matches a given criteria. ViewAction - Provide instructions to perform an Action on view object. ViewAssertion - Allows to check if some view object state matches with given criteria. This can make the Test fail.
  • 11. ViewMatcher Matcher Categories ● User Properties Commun component attributes ● UI Properties Commun UI component state ● Object Group, Logic and Text helpers ● Hierarchy Identifiers based on relationship ● Input Type support ● Class Identifiers based on object class ● Root Window holding view object
  • 12. Let’s see it on Code! import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) public class MyActivityTest { @Rule public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class); @Test public void testClickOKButtonAnd() { //Find a button with text 'play' onView(withText(R.string.play)) } }
  • 13. Action Categories ● Click/Press Commun tap actions ● Gestures Swipe and Scroll actions ● Text Editable actions ViewActions
  • 14. Cool, but and the Code? import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) public class MyActivityTest { @Rule public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class); @Test public void testClickOKButtonAnd() { //Click on button with text 'play' onView(withText(R.string.play)).perform(click()) } }
  • 15. Assertions Categories ● Generic Helpers assertions ● Layout Overlay relationship ● Positions View positions relationship ViewAssertions
  • 16. OK, but I want see Code! import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; @RunWith(AndroidJUnit4.class) public class MyActivityTest { @Rule public ActivityTestRule<MyActivity> mActivityRule = new ActivityTestRule<>(MyActivity.class); @Test public void testClickOKButtonAnd() { //Click on button with text 'play' and Check if text change to 'stop' onView(withText(R.string.play)).perform(click()).check(matches(withText(R.string.stop))); } } //Click on button with text 'play'. Check if view with id btPlayStop has text 'stop' onView(withText(R.string.play)).perform(click()); onView(withId(R.id.btPlayStop)).check(matches(withText(R.string.stop))); //Click on item with text 'Track 3’ in a list of strings. onData(allOf(is(instanceOf(String.class)), is("Track 3"))).perform(click());
  • 18. Junit Annotations @BeforeClass The method is executed before all test methods @Before This method is executed before each test method @AfterClass This method is executed after all test methods @After This method is executed after each test method @BeforeClass public static void setUp() { ... } @Before public static void setupForEachTest() { ... } @Test public void test1() { ... } @Test public void test2() { … } @After public static void undoSetupForEachTest() { … } @AfterClass public static void undoSetup() { … }
  • 19. ● Espresso-Contrib Contains Actions to RecyclerView and system components like Pickers ● Espresso-Intents Allows to Check or Mock response of started intents ● Espresso-Idling-Resource Enable to define new resources to Espresso wait before proceed ● UI Automator Let you do BlackBox test actions on system and third party apps Extra Libraries
  • 20. DrawerActions ○ openDrawer(int drawerLayoutId) ○ closeDrawer(int drawerLayoutId) Espresso-Contrib DrawerMatches ○ isOpen() ○ isClosed()
  • 21. RecyclerViewActions Needed because recyclerView extends ViewGroup, not AdapterView, so no onData for it. Espresso-Contrib Actions ○ actionOnHolderItem(Matcher<VH> viewHolderMatcher, ViewAction viewAction) ○ actionOnItem(Matcher<View> itemViewMatcher, ViewAction viewAction) ○ actionOnItemAtPosition(int position, ViewAction viewAction) Scroll ○ scrollTo(Matcher<View> itemViewMatcher) ○ scrollToHolder(Matcher<VH> viewHolderMatcher) ○ scrollToPosition(int position)
  • 22. PickerActions Needed for interact with DatePicker and TimerPicker Espresso-Contrib TimePicker ○ setTime(int hours, int minutes) DatePicker ○ setDate(int year, int monthOfYear, int dayOfMonth)
  • 23. ❖ intended(intentMatcher) Allows validation of Intents sent out by the application under test. Espresso-Intents ❖ intending(intentMatcher) .respondWith(activityResult) Enables stubbing the response of Intents sent by startActivityForResult “It’s like Mockito, but for android intents.” Matcher Categories ● Intent Commun intent parameters ● URI URI attributes validations ● Component Name Component class and package validations ● Bundle Search intent based on Entry, Key or Value
  • 24. “ UI Automator is well-suited for writing black box-style automated tests” UI Automator UIDevice UISelector ○ findObject(UiSelector selector) ○ findObjects(BySelector selector) ○ takeScreenshot(File storePath) ○ pressHome() / Back / Menu / RecentApps ○ pressEnder() / Search / KeyCode(int keyCode) ○ click(int x, int y) ○ swipe(int initX, int initY, int endX, int endY, int steps) ○ openNotification() ○ openQuickSettings() ○ setOrientationLeft() / Right() / Natural() ○ sleep() / wakeUp() / isScreenOn() ○ checked(boolean val) ○ focusable(boolean val) ○ className(Class<T> type) ○ description(String desc) ○ resourceId(String id) ○ text(String text) ○ click() / AndWaitForNewWindow() ○ exists() ○ getText() / setText(String text) / clearTextField() ○ swipeUp(int steps) Down/Left/Right UIObject
  • 25. Cool, I want see it on Code! import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import android.support.test.uiautomator.UiDevice; import android.support.test.uiautomator.UiSelector; @RunWith(AndroidJUnit4.class) public class MyActivityTest { @Test public void openMemoAndAddANewNote() throws Exception { UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); } } //Go to launcher home uiDevice.pressHome(); //click apps button to open apps drawer uiDevice.findObject(new UiSelector().description("Apps")).clickAndWaitForNewWindow(); //open calculator uiDevice.findObject(new UiSelector().text("Calculator")).clickAndWaitForNewWindow(); //Calculate 3*9 uiDevice.findObject(new UiSelector().description("3")).click(); uiDevice.findObject(new UiSelector().description("Multiply")).click(); uiDevice.findObject(new UiSelector().description("9")).click(); uiDevice.findObject(new UiSelector().description("equal")).click(); //create a selector for result display text based on its resourceId UiSelector resultSelector = new UiSelector().resourceId("com.android.calculator2:id/display_Res_Text"); //check result assertEquals("equal 27", uiDevice.findObject(resultSelector).getText());
  • 26. “ UI Automator is well-suited for writing black box-style automated tests” UI Automator Viewer
  • 27. DEMO I want Espresso in Action!
  • 28. ● Get the application context ● Get the test application context ● Obtain the context of activity to be tested ● The withText() method can be used with a string resource id Development Tips InstrumentationRegistry.getTargetContext(); Test class activityRule.getActivity().getApplicationContext(); Activity InstrumentationRegistry.getContext(); @Rule public ActivityTestRule<MyActivity> activityRule = new ActivityTestRule<>(MyActivity.class); activityRule.getActivity().getContext(); withText(R.string.test)
  • 29. ● When is expected that the test returns an exception, simply add the expected exception to Test annotation: ● However for large testing is recommended to use use ExpectedException Rule Development Tips @Test(expected = IndexOutOfBoundsException.class) public void test1() { } @Rule public ExpectedException thrown = ExpectedException.none(); @Test public void shouldTestExceptionMessage() throws IndexOutOfBoundsException { List<Object> list = new ArrayList<Object>(); thrown.expect(IndexOutOfBoundsException.class); thrown.expectMessage("Index: 0, Size: 0"); list.get(0); // execution will never get past this line }
  • 30. ● To interact with the items from Spinner, PopupMenu or similar use: '.inRoot(isPlatformPopup())' ● Stay tuned when performs swipe in a pageView to find an item in list. Perform a click in a tab for that the items can be found Commun Situations/Solution //Clicks in spinner onView(withId(R.id.spinnerCountries)).perform(click()); //Select the country Brazil and clicks in it onData(allOf(is(instanceOf(String.class)), is(“Brazil”))).inRoot(isPlatformPopup()).perform(click()); //Click TAB1 onView(withText(“TAB1”)).perform(click());
  • 31. ● As RecyclerView extends ViewGroup should be used the onView method to find items in list instead of onData ● If a RecyclerView item is not visible, unlike the ListView, a scroll must be made to the item using RecyclerViewActions.scrollTo() before interacting with the item. Commun Situations/Solution // Perform a click on first element in the RecyclerView onView(withId(R.id.recyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); Object rvTag = 0; Matcher<View> viewMatcher = hasDescendant(withText(“Item 100”)); onView(withTagValue(is(rvTag))).perform(RecyclerViewActions.scrollTo(viewMatcher));
  • 32. ● To check whether a toast was displayed ● To perform an action conditionally, we can override the method withFailureHandler, then if the check fails, instead of finishing the test, the method handle is called Commun Situations/Solution //Get the decorView View activityDecorView = mActivityRule.getActivity().getWindow().getDecorView(); onView(withText(TOAST_TEXT)).inRoot(withDecorView(not(activityDecorView))).check(isDisplayed()); onView(withText(R.string.dialog_config_app)).withFailureHandler(new FailureHandler() { @Override public void handle(Throwable throwable, Matcher<View> matcher) { onView(withText(android.R.string.ok)).perform(click()); } }).check(doesNotExist());
  • 33. Cool Links: ● https://code.google.com/p/android-test-kit/ ● https://github.com/vgrec/EspressoExamples/ ● http://www.vogella.com/tutorials/Mockito/article.html ● https://github.com/junit-team/junit/wiki/Exception-testing ● https://developer.android.com/tools/testing-support-library/index.html ● https://github.com/googlesamples/android-testing/tree/master/espresso ● https://androidresearch.wordpress.com/2015/04/04/an-introduction-to-espresso Questions?