SlideShare a Scribd company logo
1 of 135
Download to read offline
DroidCon 2014 - Robotium vs espresso_droidcon
DroidCon 2014 - Robotium vs espresso_droidcon
Robotiumvs Espresso 
Get ready to rumble !
DroidCon 2014 - Robotium vs espresso_droidcon
Thomas Guerin
Thomas Guerin 
Développeur Android
Thomas Guerin 
Développeur Android 
Tests addict
Thomas Guerin 
Développeur Android 
Tests addict 
Niveau 15 à Destiny
Robotium vs Espresso : Get ready to rumble !
Robotium vs Espresso : Get ready to rumble ! 
Pourquoi ne pas faire de tests ? 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Pourquoi ne pas faire de tests ? 
“Mes tests durent des heures !” 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Pourquoi ne pas faire de tests ? 
“Mes tests durent des heures !” 
“Tester ce n’est pas toujours simple !” 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Pourquoi ne pas faire de tests ? 
“Mes tests durent des heures !” 
“Tester ce n’est pas toujours simple !” 
“Mes tests échouent aléatoirement !” 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Pourquoi ne pas faire de tests ? 
“Mes tests durent des heures !” 
“Tester ce n’est pas toujours simple !” 
“Mes tests échouent aléatoirement !” 
“Je vais devoir corriger les tests alors que je 
n’ai presque rien modifié” 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un test doit être… 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un test doit être… 
Simple 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un test doit être… 
Simple Rapide 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un test doit être… 
Simple Rapide Fiable 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un test doit être… 
Simple Rapide Fiable Durable 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un mauvais exemple 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un mauvais exemple 
// Start the main activity of the application under test 
mActivity = getActivity(); 
! 
// Get a handle to the Activity object's main UI widget, a Spinner 
mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); 
! 
// Set the Spinner to a known position 
mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); 
! 
// Stop the activity - The onDestroy() method should save the state of the Spinner 
mActivity.finish(); 
! 
// Re-start the Activity - the onResume() method should restore the state of the Spinner 
mActivity = getActivity(); 
! 
// Get the Spinner's current position 
int currentPosition = mActivity.getSpinnerPosition(); 
! 
// Assert that the current position is the same as the starting position 
assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Un mauvais exemple 
// Start the main activity of the application under test 
mActivity = getActivity(); 
! 
// Get a handle to the Activity object's main UI widget, a Spinner 
mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); 
! 
// Set the Spinner to a known position 
mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); 
! 
// Stop the activity - The onDestroy() method should save the state of the Spinner 
mActivity.finish(); 
! 
// Re-start the Activity - the onResume() method should restore the state of the Spinner 
mActivity = getActivity(); 
! 
// Get the Spinner's current position 
int currentPosition = mActivity.getSpinnerPosition(); 
! 
// Assert that the current position is the same as the starting position 
assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les combattants 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les combattants 
Robotium 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les combattants 
#Droidcon #Robotium #Espresso 
VS 
Robotium Espresso 
@Tom404_
DroidCon 2014 - Robotium vs espresso_droidcon
Préparation
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Dépendances Gradle 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Dépendances Gradle 
Robotium 
dependencies { 
androidTestCompile ‘com.jayway.android.robotium:robotium-solo:5.2.1' 
androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0' 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Dépendances Gradle 
Espresso 
dependencies { 
/* Jars récupérés depuis https://code.google.com/p/android-test-kit */ 
androidTestCompile files(‘libs/espresso-1.1.jar’, ‘libs/espresso-contrib-1.1.jar', 
‘libs/testrunner-1.1.jar', 'libs/testrunner-runtime-1.1.jar') 
androidTestCompile 'com.google.guava:guava:14.0.1', 
'com.squareup.dagger:dagger:1.1.0', 
'org.hamcrest:hamcrest-core:1.1', 
'org.hamcrest:hamcrest-integration:1.1', 
'org.hamcrest:hamcrest-library:1.1' 
} 
android.packagingOptions { 
exclude 'META-INF/LICENSE.txt' 
exclude 'LICENSE.txt' 
exclude 'META-INF/LICENSE' 
exclude 'META-INF/NOTICE' 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Dépendances Gradle 
Double Espresso 
dependencies { 
androidTestCompile ’com.jakewharton.espresso:espresso:1.1-r3’, 
‘com.jakewharton.espresso:espresso-support-v4:1.1-r3' 
} 
android.packagingOptions { 
exclude 'META-INF/LICENSE.txt' 
exclude 'LICENSE.txt' 
exclude 'META-INF/LICENSE' 
exclude 'META-INF/NOTICE' 
} 
https://github.com/JakeWharton/double-espresso 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Test Runner 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Test Runner 
Robotium utilise le test runner du sdk 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Test Runner 
Robotium utilise le test runner du sdk 
Espresso nécessite un test runner spécifique 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Test Runner 
Robotium utilise le test runner du sdk 
Espresso nécessite un test runner spécifique 
defaultConfig { 
testInstrumentationRunner 
"com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner" 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
GoogleInstrumentationTestRunner 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
GoogleInstrumentationTestRunner 
onCreate de l'application finalisée avant le début des tests 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
GoogleInstrumentationTestRunner 
onCreate de l'application finalisée avant le début des tests 
Instrumentation terminée == activités finies 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
GoogleInstrumentationTestRunner 
onCreate de l'application finalisée avant le début des tests 
Instrumentation terminée == activités finies 
Monitoring des activités plus fiable 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
GoogleInstrumentationTestRunner 
onCreate de l'application finalisée avant le début des tests 
Instrumentation terminée == activités finies 
Monitoring des activités plus fiable 
Peut être utilisé avec d'autres librairies 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Initialisation 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Initialisation 
Robotium 
public class SimpleActionsTest extends ActivityInstrumentationTestCase2<MainActivity> { 
! 
private Solo solo; 
! 
public void setUp() throws Exception { 
super.setUp(); 
solo = new Solo(getInstrumentation(), getActivity()); 
} 
! 
public void tearDown() throws Exception { 
solo.finishOpenedActivities(); 
super.tearDown(); 
} 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Initialisation 
Espresso 
public class SimpleActionsTest extends ActivityInstrumentationTestCase2<MainActivity> { 
! 
@Override 
protected void setUp() throws Exception { 
super.setUp(); 
// Espresso ne va pas lancer l'activité pour nous 
getActivity(); 
} 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
DroidCon 2014 - Robotium vs espresso_droidcon
Expressivité
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
Robotium 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
#Droidcon #Robotium #Espresso 
Solo 
Robotium 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
clickOnActionBarHome() 
clickOnButton(int index) 
searchText(String text) 
pressSoftKeyboardNextButton() 
clickOnImageButton(int index) 
scrollDownList(int index) 
clearEditText(int index) 
scrollDown() 
clickOnToggleButton(String text) 
pressMenuItem(int index) 
#Droidcon #Robotium #Espresso 
Solo 
getView(int viewId) 
drag(…) 
clickInList(int line, int index) 
goBack() 
setNavigationDrawer(int status) 
clickOnActionBarItem(int id) 
getButton(int index) 
scrollToBottom() searchEditText(String text) 
pressSoftKeyboardSearchButton() 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
// Récupération de la vue 
Button myButton = (TextView) solo.getView(R.id.my_button); 
! 
// Assertions (AssertJ Android) 
assertThat(myButton).hasText(“My button”).isVisible(); 
! 
// Clic sur la vue 
solo.clickOnView(myButton) 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
Librairie de matchers 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
Librairie de matchers 
assertThat("Hello", equalTo("Hello")) 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
Librairie de matchers 
assertThat("Hello", equalTo("Hello")) 
! 
// Sucre syntaxique 
assertThat(“Hello", is("Hello")) 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
Librairie de matchers 
assertThat("Hello", equalTo("Hello")) 
! 
// Sucre syntaxique 
assertThat(“Hello", is("Hello")) 
! 
// De nombreux matchers disponibles 
allOf not instanceOf hasProperty equalToIgnoringCase 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest 
Librairie de matchers 
assertThat("Hello", equalTo("Hello")) 
! 
// Sucre syntaxique 
assertThat(“Hello", is("Hello")) 
! 
// De nombreux matchers disponibles 
allOf not instanceOf hasProperty equalToIgnoringCase 
Possibilité de composition 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest custom matcher 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Hamcrest custom matcher 
public class IsNotANumber extends TypeSafeMatcher<Double> { 
! 
@Override 
public boolean matchesSafely(Double number) { 
return number.isNaN(); 
} 
! 
public void describeTo(Description description) { 
description.appendText("not a number"); 
} 
! 
public static Matcher<Double> notANumber() { 
return new IsNotANumber(); 
} 
! 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
Espresso 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso withId()! 
onView(Matcher<View>)! 
onData(Matcher<Object> 
#Droidcon #Robotium #Espresso 
withText(text)! 
hasSibling(Matcher<View>) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
#Droidcon #Robotium #Espresso 
withId()! 
withText(text)! 
hasSibling(Matcher<View>) 
ViewActions 
click()! 
typeText(text) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
#Droidcon #Robotium #Espresso 
withId()! 
withText(text)! 
hasSibling(Matcher<View>) 
ViewActions 
click()! 
typeText(text) 
ViewAssertions 
doesNotExist()! 
matches(Matcher<View>) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
ViewInteraction / DataInteraction 
perform(ViewAction)! 
check(ViewAssertion) 
#Droidcon #Robotium #Espresso 
withId()! 
withText(text)! 
hasSibling(Matcher<View>) 
ViewActions 
click()! 
typeText(text) 
ViewAssertions 
doesNotExist()! 
matches(Matcher<View>) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
ViewInteraction / DataInteraction 
perform(ViewAction)! 
check(ViewAssertion) 
#Droidcon #Robotium #Espresso 
withId()! 
withText(text)! 
hasSibling(Matcher<View>) 
ViewActions 
click()! 
typeText(text) 
ViewAssertions 
doesNotExist()! 
matches(Matcher<View>) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
API overview 
ViewMatchers Espresso 
Espresso 
onView(Matcher<View>)! 
onData(Matcher<Object> 
ViewInteraction / DataInteraction 
perform(ViewAction)! 
check(ViewAssertion) 
#Droidcon #Robotium #Espresso 
withId()! 
withText(text)! 
hasSibling(Matcher<View>) 
ViewActions 
click()! 
typeText(text) 
ViewAssertions 
doesNotExist()! 
matches(Matcher<View>) 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
onView(allOf(withId(R.id.my_button), withText(“My Button”))) 
.check(matches(isDisplayed())) 
.perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
onView(allOf(withId(R.id.my_button), withText(“My Button”))) 
.check(matches(isDisplayed())) 
.perform(click()); 
! 
// Une simple extraction de méthode permet de simplifier 
onView(withIdAndText(R.id.my_button, "My Button”)) 
.check(matches(isDisplayed())) 
.perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
onView(allOf(withId(R.id.my_button), withText(“My Button”))) 
.check(matches(isDisplayed())) 
.perform(click()); 
! 
// Une simple extraction de méthode permet de simplifier 
onView(withIdAndText(R.id.my_button, "My Button”)) 
.check(matches(isDisplayed())) 
.perform(click()); 
! 
// Si le bouton n'est pas affiché le perform(click()) échouera 
onView(withIdAndText(R.id.my_button, "My Button")).perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Exemple 
onView(allOf(withId(R.id.my_button), withText(“My Button”))) 
.check(matches(isDisplayed())) 
.perform(click()); 
! 
// Une simple extraction de méthode permet de simplifier 
onView(withIdAndText(R.id.my_button, "My Button”)) 
.check(matches(isDisplayed())) 
.perform(click()); 
! 
// Si le bouton n'est pas affiché le perform(click()) échouera 
onView(withIdAndText(R.id.my_button, "My Button")).perform(click()); 
Manque de restrictions = AmbiguousViewMatcherException 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Listview 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Listview 
Robotium 
// Clic sur item 
solo.clickOnText("textToFind"); 
! 
// Si jamais il y'en a plusieurs -> utilisation d'un index 
solo.clickOnText("textToFind", 3); 
! 
// Ou choisir directement la ligne 
solo.clickInList(2); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Listview 
Espresso 
onData(allOf(is(instanceOf(String.class)), is("textToFind"))).perform(click()); 
! 
// Ou directement à une position 
onData(is(instanceOf(String.class))).atPosition(0).perform(click()); 
! 
// Possibilité de préciser une listview, utile pour le view pager 
onData(allOf(is(instanceOf(String.class)), is("textToFind"))) 
.inAdapterView(withId(R.id.my_list)).perform(click()); 
! 
// Interaction avec une vue enfant de la ligne 
onData(allOf(is(instanceOf(String.class)), is("textToFind"))) 
.onChildView(withId(R.id.my_child)) 
.perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Listview 
Espresso : cas plus complexe 
// Type renvoyé par la méthode getItem de l'adapteur 
public class Item { 
public String name; 
public String itemContent; 
} 
! 
onData(allOf(is(instanceOf(Item.class)), hasProperty(“name", equalTo(“nameToFind")))) 
.perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Listview 
Espresso : custom matcher 
public static Matcher<Object> withItemName(final Matcher<String> itemTextMatcher){ 
return new BoundedMatcher<Object, Item>(Item.class) { 
@Override 
public boolean matchesSafely(Item item) { 
return itemTextMatcher.matches(item.name); 
} 
! 
@Override 
public void describeTo(Description description) { 
description.appendText("with item name: "); 
itemTextMatcher.describeTo(description); 
} 
}; 
} 
onData(withItemName(equalTo("nameToFind"))).perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Webview 
Robotium 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Webview 
Robotium 
Possibilité d’interagir avec les webviews 
•solo.getWebElements(by) 
•solo.clickOnWebElement(by) 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Webview 
Robotium 
Possibilité d’interagir avec les webviews 
•solo.getWebElements(by) 
•solo.clickOnWebElement(by) 
Plusieurs types de recherches disponibles 
•By.id(String id) 
•By.className(String className) 
•By.textContent(String textContent) 
•By.name(String name) 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Webview 
Espresso 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Webview 
Espresso 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Navigation Drawer 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Navigation Drawer 
Robotium 
// Attention l'id du frame layout du menu doit absolument être "left_drawer" 
solo.setNavigationDrawer(Solo.OPENED); 
! 
solo.setNavigationDrawer(Solo.CLOSED); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Navigation Drawer 
Robotium 
// Attention l'id du frame layout du menu doit absolument être "left_drawer" 
solo.setNavigationDrawer(Solo.OPENED); 
! 
solo.setNavigationDrawer(Solo.CLOSED); 
Espresso 
DrawerActions.openDrawer(R.id.drawer_layout); 
! 
DrawerActions.closeDrawer(R.id.drawer_layout); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Action bar 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Action bar 
Robotium 
solo.clickOnActionBarItem(R.id.action_example); 
! 
// Cas de l'action bar overflow 
solo.sendKey(KeyEvent.KEYCODE_MENU); 
solo.clickOnText("action"); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Action bar 
Robotium 
solo.clickOnActionBarItem(R.id.action_example); 
! 
// Cas de l'action bar overflow 
solo.sendKey(KeyEvent.KEYCODE_MENU); 
solo.clickOnText("action"); 
Espresso 
onView(withId(R.id_action_example)).perform(click()); 
! 
// Cas de l'action bar overflow 
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); 
onView(withText("action")).perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Back button & Keyboard 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Back button & Keyboard 
Robotium 
solo.goBack(); 
// solo.goBack() est aussi utilisé pour fermer le clavier 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Back button & Keyboard 
Robotium 
solo.goBack(); 
// solo.goBack() est aussi utilisé pour fermer le clavier 
Espresso 
Espresso.pressBack(); 
Espresso.closeSoftKeyboard(); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les messages d’erreur 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les messages d’erreur 
Robotium 
! 
// Récupération d’une vue inexistante 
solo.getView(1234); 
!j 
unit.framework.AssertionFailedError: View with id: '1234' is not found! 
at com.robotium.solo.Solo.getView(Solo.java:2008) 
at com.robotium.solo.Solo.getView(Solo.java:1988) 
at 
fr.droidcon.robotium.vs.espresso.samples.test.robotium.SimpleActionsTest.testClickButton(SimpleAct 
ionsTest.java:28) 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Les messages d’erreur 
Espresso 
! 
// Récupération d’une vue inexistante 
onView(withId(1234)); 
com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: No views in hierarchy 
found matching: with id: is <1234> 
If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from 
one of the following AdapterViews:android.widget.ListView{426f6f18 VFED.VC. ......ID 0,0-720,1557} 
- android.widget.ListView{4269c598 V.ED.VC. ........ 48,393-1032,1509 #7f070042 app:id/my_list} 
! 
View Hierarchy: 
+>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1776, has-focus=true, has-focusable=true, 
has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout- 
requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, 
x=0.0, y=0.0, child-count=1} 
| 
+->ActionBarOverlayLayout{id=16909075, res-name=action_bar_overlay_layout, visibility=VISIBLE, 
width=1080, height=1776, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable= 
false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected= 
false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count= 
3} 
| 
+-->FrameLayout{id=16908290, res-name=content, visibility=VISIBLE, width=1080, height=1557, 
has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is- 
#Droidcon #Robotium #Espresso @Tom404_
DroidCon 2014 - Robotium vs espresso_droidcon
Enchaînements
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Wait and See 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Wait and See 
Robotium repose sur le principe de wait & see 
•solo.waitForActivity(Class class, int timeout) 
• solo.waitForCondition(Condition condition, int timeout) 
• solo.waitForDialogToOpen() 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Wait and See 
Robotium repose sur le principe de wait & see 
•solo.waitForActivity(Class class, int timeout) 
• solo.waitForCondition(Condition condition, int timeout) 
• solo.waitForDialogToOpen() 
solo.clickOnView(R.id.start_activity_button); 
! 
// On attend que la vue apparaisse avant d'agir 
solo.waitForView(R.id.view_in_new_activity); 
! 
solo.clickOnView(R.id.view_in_new_activity); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
Entrée en jeu du GoogleInstrumentationTestRunner 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
Entrée en jeu du GoogleInstrumentationTestRunner 
Monitoring plus fin des activités et des ressources 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
Entrée en jeu du GoogleInstrumentationTestRunner 
Monitoring plus fin des activités et des ressources 
Analyse du ThreadUI pour savoir quand agir 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
Entrée en jeu du GoogleInstrumentationTestRunner 
Monitoring plus fin des activités et des ressources 
Analyse du ThreadUI pour savoir quand agir 
Pas de wait 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Finis de dormir ! 
Entrée en jeu du GoogleInstrumentationTestRunner 
Monitoring plus fin des activités et des ressources 
Analyse du ThreadUI pour savoir quand agir 
Pas de wait 
onView(withId(R.id.start_activity_button)).perform(click()); 
! 
onView(withId(R.id.view_in_new_activity)).perform(click()); 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Idle mais actif ! 
#Droidcon #Robotium #Espresso @Tom404_
Robotium vs Espresso : Get ready to rumble ! 
Idle mais actif ! 
Possibilité d'enregistrer des idlingResources 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource { 
private int threadCount = 0; 
private ResourceCallback resourceCallback; 
... 
@Override 
public synchronized void execute(Runnable r) { 
threadCount++; 
super.execute(r); 
} 
@Override 
public synchronized boolean isIdleNow() { 
return threadCount == 0; 
} 
@Override 
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { 
this.resourceCallback = resourceCallback; 
} 
@Override 
protected synchronized void afterExecute(Runnable r, Throwable t) { 
super.afterExecute(r, t); 
threadCount--; 
if (resourceCallback != null && isIdleNow()) { 
resourceCallback.onTransitionToIdle(); 
} 
} 
} 
#Droidcon #Robotium #Espresso 
@Tom404_
Robotium vs Espresso : Get ready to rumble ! 
class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource { 
private int threadCount = 0; 
private ResourceCallback resourceCallback; 
... 
@Override 
public synchronized void execute(Runnable r) { 
threadCount++; 
super.execute(r); 
} 
@Override 
public synchronized boolean isIdleNow() { 
return threadCount == 0; 
} 
@Override 
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { 
this.resourceCallback = resourceCallback; 
} 
@Override 
protected synchronized void afterExecute(Runnable r, Throwable t) { 
super.afterExecute(r, t); 
threadCount--; 
if (resourceCallback != null && isIdleNow()) { 
resourceCallback.onTransitionToIdle(); 
} 
} 
} 
Espresso.registerIdlingResources(espressoThreadPool); 
#Droidcon #Robotium #Espresso 
@Tom404_
DroidCon 2014 - Robotium vs espresso_droidcon
Conclusion
DroidCon 2014 - Robotium vs espresso_droidcon
Questions ?
DroidCon 2014 - Robotium vs espresso_droidcon

More Related Content

Viewers also liked

PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La Boate
PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La BoatePACA Lights by PACA Labs - 8 décembre 2014, Marseille, La Boate
PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La BoateFing
 
Prez infolab-bilan2015
Prez infolab-bilan2015Prez infolab-bilan2015
Prez infolab-bilan2015Fing
 
como subir presentaciones a slideshare.
como subir presentaciones a slideshare.como subir presentaciones a slideshare.
como subir presentaciones a slideshare.lizethortegaelec
 
Scrum day 2013 sponsoring package
Scrum day 2013 sponsoring packageScrum day 2013 sponsoring package
Scrum day 2013 sponsoring packageXavier Warzee
 
T, suzanne valadon et ses souvenirs de modèle
T, suzanne valadon et ses souvenirs de modèleT, suzanne valadon et ses souvenirs de modèle
T, suzanne valadon et ses souvenirs de modèleJoin-Lambert Blaise
 
Presentacion Da Tectonica De Placas
Presentacion Da Tectonica De PlacasPresentacion Da Tectonica De Placas
Presentacion Da Tectonica De Placasrake777
 
memoguide_CHASSEZAC
memoguide_CHASSEZACmemoguide_CHASSEZAC
memoguide_CHASSEZACRémi MASSOT
 
Belllissima nature s-best_photography
Belllissima  nature s-best_photographyBelllissima  nature s-best_photography
Belllissima nature s-best_photographyMaria Grazia
 
Remess actes de_la_rencontre_africaine_kenitra_2010
Remess actes de_la_rencontre_africaine_kenitra_2010Remess actes de_la_rencontre_africaine_kenitra_2010
Remess actes de_la_rencontre_africaine_kenitra_2010AFRICAESS
 
Curso de primeros auxilios CPR de Mérida
Curso de primeros auxilios CPR de MéridaCurso de primeros auxilios CPR de Mérida
Curso de primeros auxilios CPR de Méridasanticampo
 
Tenant Improvement - Alert Logic
Tenant Improvement - Alert LogicTenant Improvement - Alert Logic
Tenant Improvement - Alert LogicKelcey Peters
 
Presentation Way To Blue Fr
Presentation Way To Blue FrPresentation Way To Blue Fr
Presentation Way To Blue FrWay to Blue
 
definiciones preliminares2007
 definiciones preliminares2007 definiciones preliminares2007
definiciones preliminares2007Isidorogg
 
Manejo básico netvibes
Manejo básico netvibesManejo básico netvibes
Manejo básico netvibesluciasn
 
GreenIvory : produits & services
GreenIvory : produits & servicesGreenIvory : produits & services
GreenIvory : produits & servicesJean-Georges Perrin
 

Viewers also liked (20)

PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La Boate
PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La BoatePACA Lights by PACA Labs - 8 décembre 2014, Marseille, La Boate
PACA Lights by PACA Labs - 8 décembre 2014, Marseille, La Boate
 
Prez infolab-bilan2015
Prez infolab-bilan2015Prez infolab-bilan2015
Prez infolab-bilan2015
 
Power Point2003
Power Point2003Power Point2003
Power Point2003
 
como subir presentaciones a slideshare.
como subir presentaciones a slideshare.como subir presentaciones a slideshare.
como subir presentaciones a slideshare.
 
Scrum day 2013 sponsoring package
Scrum day 2013 sponsoring packageScrum day 2013 sponsoring package
Scrum day 2013 sponsoring package
 
T, suzanne valadon et ses souvenirs de modèle
T, suzanne valadon et ses souvenirs de modèleT, suzanne valadon et ses souvenirs de modèle
T, suzanne valadon et ses souvenirs de modèle
 
tariq-cert
tariq-certtariq-cert
tariq-cert
 
Presentacion Da Tectonica De Placas
Presentacion Da Tectonica De PlacasPresentacion Da Tectonica De Placas
Presentacion Da Tectonica De Placas
 
memoguide_CHASSEZAC
memoguide_CHASSEZACmemoguide_CHASSEZAC
memoguide_CHASSEZAC
 
Belllissima nature s-best_photography
Belllissima  nature s-best_photographyBelllissima  nature s-best_photography
Belllissima nature s-best_photography
 
9 suggestions de cadeaux
9 suggestions de cadeaux9 suggestions de cadeaux
9 suggestions de cadeaux
 
Remess actes de_la_rencontre_africaine_kenitra_2010
Remess actes de_la_rencontre_africaine_kenitra_2010Remess actes de_la_rencontre_africaine_kenitra_2010
Remess actes de_la_rencontre_africaine_kenitra_2010
 
Curso de primeros auxilios CPR de Mérida
Curso de primeros auxilios CPR de MéridaCurso de primeros auxilios CPR de Mérida
Curso de primeros auxilios CPR de Mérida
 
Tenant Improvement - Alert Logic
Tenant Improvement - Alert LogicTenant Improvement - Alert Logic
Tenant Improvement - Alert Logic
 
Presentation Way To Blue Fr
Presentation Way To Blue FrPresentation Way To Blue Fr
Presentation Way To Blue Fr
 
Pop
PopPop
Pop
 
Pré
PréPré
Pré
 
definiciones preliminares2007
 definiciones preliminares2007 definiciones preliminares2007
definiciones preliminares2007
 
Manejo básico netvibes
Manejo básico netvibesManejo básico netvibes
Manejo básico netvibes
 
GreenIvory : produits & services
GreenIvory : produits & servicesGreenIvory : produits & services
GreenIvory : produits & services
 

Similar to DroidCon 2014 - Robotium vs espresso_droidcon

Acciones para AmigoBot
Acciones para AmigoBotAcciones para AmigoBot
Acciones para AmigoBotjhonsoomelol
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceshipsSabin Marcu
 
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...Badoo
 
Testing with Docker
Testing with DockerTesting with Docker
Testing with Dockertoffermann
 
Hotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptHotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptSergio Padrino Recio
 
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...Hinling Yeung
 
Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Anna Schneider
 
Practical unit testing 2014
Practical unit testing 2014Practical unit testing 2014
Practical unit testing 2014Andrew Fray
 
Mobile Development integration tests
Mobile Development integration testsMobile Development integration tests
Mobile Development integration testsKenneth Poon
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMockYing Zhang
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manormartinbtt
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...Yevgeniy Brikman
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplosvinibaggio
 
greach 2014 marco vermeulen bdd using cucumber jvm and groovy
greach 2014 marco vermeulen bdd using cucumber jvm and groovygreach 2014 marco vermeulen bdd using cucumber jvm and groovy
greach 2014 marco vermeulen bdd using cucumber jvm and groovyJessie Evangelista
 

Similar to DroidCon 2014 - Robotium vs espresso_droidcon (20)

Espresso devoxx 2014
Espresso devoxx 2014Espresso devoxx 2014
Espresso devoxx 2014
 
RoboSpock Poznań ADG 2016
RoboSpock Poznań ADG 2016RoboSpock Poznań ADG 2016
RoboSpock Poznań ADG 2016
 
RoboSpock
RoboSpockRoboSpock
RoboSpock
 
Acciones para AmigoBot
Acciones para AmigoBotAcciones para AmigoBot
Acciones para AmigoBot
 
How to not blow up spaceships
How to not blow up spaceshipsHow to not blow up spaceships
How to not blow up spaceships
 
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...
Mobile Web Test Automation: to the Desktop! - Alexander Bayandin - Mobile Tes...
 
Testing with Docker
Testing with DockerTesting with Docker
Testing with Docker
 
Hotfixing iOS apps with Javascript
Hotfixing iOS apps with JavascriptHotfixing iOS apps with Javascript
Hotfixing iOS apps with Javascript
 
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...
The Chronicle of iPhone Automation -- From Frank to UISpec to UIAutomation to...
 
Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)Django for IoT: From hackathon to production (DjangoCon US)
Django for IoT: From hackathon to production (DjangoCon US)
 
Practical unit testing 2014
Practical unit testing 2014Practical unit testing 2014
Practical unit testing 2014
 
Mobile Development integration tests
Mobile Development integration testsMobile Development integration tests
Mobile Development integration tests
 
Mockito with a hint of PowerMock
Mockito with a hint of PowerMockMockito with a hint of PowerMock
Mockito with a hint of PowerMock
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Testing smells
Testing smellsTesting smells
Testing smells
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
 
Deviceanywhere studio 5.1
Deviceanywhere studio 5.1Deviceanywhere studio 5.1
Deviceanywhere studio 5.1
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
greach 2014 marco vermeulen bdd using cucumber jvm and groovy
greach 2014 marco vermeulen bdd using cucumber jvm and groovygreach 2014 marco vermeulen bdd using cucumber jvm and groovy
greach 2014 marco vermeulen bdd using cucumber jvm and groovy
 

More from Publicis Sapient Engineering

XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humain
XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humainXebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humain
XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humainPublicis Sapient Engineering
 
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveur
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveurXebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveur
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveurPublicis Sapient Engineering
 
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...Publicis Sapient Engineering
 
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin XebiCon'18 - Des notebook pour le monitoring avec Zeppelin
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin Publicis Sapient Engineering
 
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?Publicis Sapient Engineering
 
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?Publicis Sapient Engineering
 
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribué
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribuéXebiCon'18 - Boostez vos modèles avec du Deep Learning distribué
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribuéPublicis Sapient Engineering
 
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...Publicis Sapient Engineering
 
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !Publicis Sapient Engineering
 
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des dataviz
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des datavizXebiCon'18 - Comment fausser l'interprétation de vos résultats avec des dataviz
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des datavizPublicis Sapient Engineering
 
XebiCon'18 - Architecturer son application mobile pour la durabilité
XebiCon'18 - Architecturer son application mobile pour la durabilitéXebiCon'18 - Architecturer son application mobile pour la durabilité
XebiCon'18 - Architecturer son application mobile pour la durabilitéPublicis Sapient Engineering
 
XebiCon'18 - Sécuriser son API avec OpenID Connect
XebiCon'18 - Sécuriser son API avec OpenID ConnectXebiCon'18 - Sécuriser son API avec OpenID Connect
XebiCon'18 - Sécuriser son API avec OpenID ConnectPublicis Sapient Engineering
 
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...Publicis Sapient Engineering
 
XebiCon'18 - La sécurité, douce illusion même en 2018
XebiCon'18 - La sécurité, douce illusion même en 2018XebiCon'18 - La sécurité, douce illusion même en 2018
XebiCon'18 - La sécurité, douce illusion même en 2018Publicis Sapient Engineering
 
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...Publicis Sapient Engineering
 
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...Publicis Sapient Engineering
 

More from Publicis Sapient Engineering (20)

XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humain
XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humainXebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humain
XebiCon'18 - L'algorithme de reconnaissance de formes par le cerveau humain
 
Xebicon'18 - IoT: From Edge to Cloud
Xebicon'18 - IoT: From Edge to CloudXebicon'18 - IoT: From Edge to Cloud
Xebicon'18 - IoT: From Edge to Cloud
 
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveur
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveurXebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveur
Xebicon'18 - Spark in jail : conteneurisez vos traitements data sans serveur
 
XebiCon'18 - Modern Infrastructure
XebiCon'18 - Modern InfrastructureXebiCon'18 - Modern Infrastructure
XebiCon'18 - Modern Infrastructure
 
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...
XebiCon'18 - La Web App d'aujourd'hui et de demain : état de l'art et bleedin...
 
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin XebiCon'18 - Des notebook pour le monitoring avec Zeppelin
XebiCon'18 - Des notebook pour le monitoring avec Zeppelin
 
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
XebiCon'18 - Event Sourcing et RGPD, incompatibles ?
 
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?
XebiCon'18 - Deno, le nouveau NodeJS qui inverse la tendance ?
 
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribué
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribuéXebiCon'18 - Boostez vos modèles avec du Deep Learning distribué
XebiCon'18 - Boostez vos modèles avec du Deep Learning distribué
 
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...
XebiCon'18 - Comment j'ai développé un jeu vidéo avec des outils de développe...
 
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !
XebiCon'18 - Les utilisateurs finaux, les oubliés de nos produits !
 
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des dataviz
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des datavizXebiCon'18 - Comment fausser l'interprétation de vos résultats avec des dataviz
XebiCon'18 - Comment fausser l'interprétation de vos résultats avec des dataviz
 
XebiCon'18 - Le développeur dans la Pop Culture
XebiCon'18 - Le développeur dans la Pop Culture XebiCon'18 - Le développeur dans la Pop Culture
XebiCon'18 - Le développeur dans la Pop Culture
 
XebiCon'18 - Architecturer son application mobile pour la durabilité
XebiCon'18 - Architecturer son application mobile pour la durabilitéXebiCon'18 - Architecturer son application mobile pour la durabilité
XebiCon'18 - Architecturer son application mobile pour la durabilité
 
XebiCon'18 - Sécuriser son API avec OpenID Connect
XebiCon'18 - Sécuriser son API avec OpenID ConnectXebiCon'18 - Sécuriser son API avec OpenID Connect
XebiCon'18 - Sécuriser son API avec OpenID Connect
 
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...
XebiCon'18 - Structuration du Temps et Dynamique de Groupes, Théorie organisa...
 
XebiCon'18 - Spark NLP, un an après
XebiCon'18 - Spark NLP, un an aprèsXebiCon'18 - Spark NLP, un an après
XebiCon'18 - Spark NLP, un an après
 
XebiCon'18 - La sécurité, douce illusion même en 2018
XebiCon'18 - La sécurité, douce illusion même en 2018XebiCon'18 - La sécurité, douce illusion même en 2018
XebiCon'18 - La sécurité, douce illusion même en 2018
 
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...
XebiCon'18 - Utiliser Hyperledger Fabric pour la création d'une blockchain pr...
 
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...
XebiCon'18 - Ce que l'histoire du métro Parisien m'a enseigné sur la création...
 

Recently uploaded

Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsSeth Reyes
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfinfogdgmi
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfDianaGray10
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024D Cloud Solutions
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfJamie (Taka) Wang
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IES VE
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?IES VE
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-pyJamie (Taka) Wang
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Websitedgelyza
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxGDSC PJATK
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemAsko Soukka
 

Recently uploaded (20)

Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
Computer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and HazardsComputer 10: Lesson 10 - Online Crimes and Hazards
Computer 10: Lesson 10 - Online Crimes and Hazards
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 
Videogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdfVideogame localization & technology_ how to enhance the power of translation.pdf
Videogame localization & technology_ how to enhance the power of translation.pdf
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdfUiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
UiPath Solutions Management Preview - Northern CA Chapter - March 22.pdf
 
Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024Artificial Intelligence & SEO Trends for 2024
Artificial Intelligence & SEO Trends for 2024
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
activity_diagram_combine_v4_20190827.pdfactivity_diagram_combine_v4_20190827.pdf
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
20230104 - machine vision
20230104 - machine vision20230104 - machine vision
20230104 - machine vision
 
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
IESVE Software for Florida Code Compliance Using ASHRAE 90.1-2019
 
How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?How Accurate are Carbon Emissions Projections?
How Accurate are Carbon Emissions Projections?
 
20230202 - Introduction to tis-py
20230202 - Introduction to tis-py20230202 - Introduction to tis-py
20230202 - Introduction to tis-py
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
COMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a WebsiteCOMPUTER 10 Lesson 8 - Building a Website
COMPUTER 10 Lesson 8 - Building a Website
 
201610817 - edge part1
201610817 - edge part1201610817 - edge part1
201610817 - edge part1
 
Cybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptxCybersecurity Workshop #1.pptx
Cybersecurity Workshop #1.pptx
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
Bird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystemBird eye's view on Camunda open source ecosystem
Bird eye's view on Camunda open source ecosystem
 

DroidCon 2014 - Robotium vs espresso_droidcon

  • 3. Robotiumvs Espresso Get ready to rumble !
  • 7. Thomas Guerin Développeur Android Tests addict
  • 8. Thomas Guerin Développeur Android Tests addict Niveau 15 à Destiny
  • 9. Robotium vs Espresso : Get ready to rumble !
  • 10. Robotium vs Espresso : Get ready to rumble ! Pourquoi ne pas faire de tests ? #Droidcon #Robotium #Espresso @Tom404_
  • 11. Robotium vs Espresso : Get ready to rumble ! Pourquoi ne pas faire de tests ? “Mes tests durent des heures !” #Droidcon #Robotium #Espresso @Tom404_
  • 12. Robotium vs Espresso : Get ready to rumble ! Pourquoi ne pas faire de tests ? “Mes tests durent des heures !” “Tester ce n’est pas toujours simple !” #Droidcon #Robotium #Espresso @Tom404_
  • 13. Robotium vs Espresso : Get ready to rumble ! Pourquoi ne pas faire de tests ? “Mes tests durent des heures !” “Tester ce n’est pas toujours simple !” “Mes tests échouent aléatoirement !” #Droidcon #Robotium #Espresso @Tom404_
  • 14. Robotium vs Espresso : Get ready to rumble ! Pourquoi ne pas faire de tests ? “Mes tests durent des heures !” “Tester ce n’est pas toujours simple !” “Mes tests échouent aléatoirement !” “Je vais devoir corriger les tests alors que je n’ai presque rien modifié” #Droidcon #Robotium #Espresso @Tom404_
  • 15. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 16. Robotium vs Espresso : Get ready to rumble ! Un test doit être… #Droidcon #Robotium #Espresso @Tom404_
  • 17. Robotium vs Espresso : Get ready to rumble ! Un test doit être… Simple #Droidcon #Robotium #Espresso @Tom404_
  • 18. Robotium vs Espresso : Get ready to rumble ! Un test doit être… Simple Rapide #Droidcon #Robotium #Espresso @Tom404_
  • 19. Robotium vs Espresso : Get ready to rumble ! Un test doit être… Simple Rapide Fiable #Droidcon #Robotium #Espresso @Tom404_
  • 20. Robotium vs Espresso : Get ready to rumble ! Un test doit être… Simple Rapide Fiable Durable #Droidcon #Robotium #Espresso @Tom404_
  • 21. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 22. Robotium vs Espresso : Get ready to rumble ! Un mauvais exemple #Droidcon #Robotium #Espresso @Tom404_
  • 23. Robotium vs Espresso : Get ready to rumble ! Un mauvais exemple // Start the main activity of the application under test mActivity = getActivity(); ! // Get a handle to the Activity object's main UI widget, a Spinner mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); ! // Set the Spinner to a known position mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); ! // Stop the activity - The onDestroy() method should save the state of the Spinner mActivity.finish(); ! // Re-start the Activity - the onResume() method should restore the state of the Spinner mActivity = getActivity(); ! // Get the Spinner's current position int currentPosition = mActivity.getSpinnerPosition(); ! // Assert that the current position is the same as the starting position assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); #Droidcon #Robotium #Espresso @Tom404_
  • 24. Robotium vs Espresso : Get ready to rumble ! Un mauvais exemple // Start the main activity of the application under test mActivity = getActivity(); ! // Get a handle to the Activity object's main UI widget, a Spinner mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01); ! // Set the Spinner to a known position mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION); ! // Stop the activity - The onDestroy() method should save the state of the Spinner mActivity.finish(); ! // Re-start the Activity - the onResume() method should restore the state of the Spinner mActivity = getActivity(); ! // Get the Spinner's current position int currentPosition = mActivity.getSpinnerPosition(); ! // Assert that the current position is the same as the starting position assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition); #Droidcon #Robotium #Espresso @Tom404_
  • 25. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 26. Robotium vs Espresso : Get ready to rumble ! Les combattants #Droidcon #Robotium #Espresso @Tom404_
  • 27. Robotium vs Espresso : Get ready to rumble ! Les combattants Robotium #Droidcon #Robotium #Espresso @Tom404_
  • 28. Robotium vs Espresso : Get ready to rumble ! Les combattants #Droidcon #Robotium #Espresso VS Robotium Espresso @Tom404_
  • 31. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 32. Robotium vs Espresso : Get ready to rumble ! Dépendances Gradle #Droidcon #Robotium #Espresso @Tom404_
  • 33. Robotium vs Espresso : Get ready to rumble ! Dépendances Gradle Robotium dependencies { androidTestCompile ‘com.jayway.android.robotium:robotium-solo:5.2.1' androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0' } #Droidcon #Robotium #Espresso @Tom404_
  • 34. Robotium vs Espresso : Get ready to rumble ! Dépendances Gradle Espresso dependencies { /* Jars récupérés depuis https://code.google.com/p/android-test-kit */ androidTestCompile files(‘libs/espresso-1.1.jar’, ‘libs/espresso-contrib-1.1.jar', ‘libs/testrunner-1.1.jar', 'libs/testrunner-runtime-1.1.jar') androidTestCompile 'com.google.guava:guava:14.0.1', 'com.squareup.dagger:dagger:1.1.0', 'org.hamcrest:hamcrest-core:1.1', 'org.hamcrest:hamcrest-integration:1.1', 'org.hamcrest:hamcrest-library:1.1' } android.packagingOptions { exclude 'META-INF/LICENSE.txt' exclude 'LICENSE.txt' exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } #Droidcon #Robotium #Espresso @Tom404_
  • 35. Robotium vs Espresso : Get ready to rumble ! Dépendances Gradle Double Espresso dependencies { androidTestCompile ’com.jakewharton.espresso:espresso:1.1-r3’, ‘com.jakewharton.espresso:espresso-support-v4:1.1-r3' } android.packagingOptions { exclude 'META-INF/LICENSE.txt' exclude 'LICENSE.txt' exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } https://github.com/JakeWharton/double-espresso #Droidcon #Robotium #Espresso @Tom404_
  • 36. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 37. Robotium vs Espresso : Get ready to rumble ! Test Runner #Droidcon #Robotium #Espresso @Tom404_
  • 38. Robotium vs Espresso : Get ready to rumble ! Test Runner Robotium utilise le test runner du sdk #Droidcon #Robotium #Espresso @Tom404_
  • 39. Robotium vs Espresso : Get ready to rumble ! Test Runner Robotium utilise le test runner du sdk Espresso nécessite un test runner spécifique #Droidcon #Robotium #Espresso @Tom404_
  • 40. Robotium vs Espresso : Get ready to rumble ! Test Runner Robotium utilise le test runner du sdk Espresso nécessite un test runner spécifique defaultConfig { testInstrumentationRunner "com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner" } #Droidcon #Robotium #Espresso @Tom404_
  • 41. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 42. Robotium vs Espresso : Get ready to rumble ! GoogleInstrumentationTestRunner #Droidcon #Robotium #Espresso @Tom404_
  • 43. Robotium vs Espresso : Get ready to rumble ! GoogleInstrumentationTestRunner onCreate de l'application finalisée avant le début des tests #Droidcon #Robotium #Espresso @Tom404_
  • 44. Robotium vs Espresso : Get ready to rumble ! GoogleInstrumentationTestRunner onCreate de l'application finalisée avant le début des tests Instrumentation terminée == activités finies #Droidcon #Robotium #Espresso @Tom404_
  • 45. Robotium vs Espresso : Get ready to rumble ! GoogleInstrumentationTestRunner onCreate de l'application finalisée avant le début des tests Instrumentation terminée == activités finies Monitoring des activités plus fiable #Droidcon #Robotium #Espresso @Tom404_
  • 46. Robotium vs Espresso : Get ready to rumble ! GoogleInstrumentationTestRunner onCreate de l'application finalisée avant le début des tests Instrumentation terminée == activités finies Monitoring des activités plus fiable Peut être utilisé avec d'autres librairies #Droidcon #Robotium #Espresso @Tom404_
  • 47. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 48. Robotium vs Espresso : Get ready to rumble ! Initialisation #Droidcon #Robotium #Espresso @Tom404_
  • 49. Robotium vs Espresso : Get ready to rumble ! Initialisation Robotium public class SimpleActionsTest extends ActivityInstrumentationTestCase2<MainActivity> { ! private Solo solo; ! public void setUp() throws Exception { super.setUp(); solo = new Solo(getInstrumentation(), getActivity()); } ! public void tearDown() throws Exception { solo.finishOpenedActivities(); super.tearDown(); } } #Droidcon #Robotium #Espresso @Tom404_
  • 50. Robotium vs Espresso : Get ready to rumble ! Initialisation Espresso public class SimpleActionsTest extends ActivityInstrumentationTestCase2<MainActivity> { ! @Override protected void setUp() throws Exception { super.setUp(); // Espresso ne va pas lancer l'activité pour nous getActivity(); } } #Droidcon #Robotium #Espresso @Tom404_
  • 53. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 54. Robotium vs Espresso : Get ready to rumble ! API overview Robotium #Droidcon #Robotium #Espresso @Tom404_
  • 55. Robotium vs Espresso : Get ready to rumble ! API overview #Droidcon #Robotium #Espresso Solo Robotium @Tom404_
  • 56. Robotium vs Espresso : Get ready to rumble ! API overview clickOnActionBarHome() clickOnButton(int index) searchText(String text) pressSoftKeyboardNextButton() clickOnImageButton(int index) scrollDownList(int index) clearEditText(int index) scrollDown() clickOnToggleButton(String text) pressMenuItem(int index) #Droidcon #Robotium #Espresso Solo getView(int viewId) drag(…) clickInList(int line, int index) goBack() setNavigationDrawer(int status) clickOnActionBarItem(int id) getButton(int index) scrollToBottom() searchEditText(String text) pressSoftKeyboardSearchButton() @Tom404_
  • 57. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 58. Robotium vs Espresso : Get ready to rumble ! Exemple #Droidcon #Robotium #Espresso @Tom404_
  • 59. Robotium vs Espresso : Get ready to rumble ! Exemple // Récupération de la vue Button myButton = (TextView) solo.getView(R.id.my_button); ! // Assertions (AssertJ Android) assertThat(myButton).hasText(“My button”).isVisible(); ! // Clic sur la vue solo.clickOnView(myButton) #Droidcon #Robotium #Espresso @Tom404_
  • 60. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 61. Robotium vs Espresso : Get ready to rumble ! Hamcrest #Droidcon #Robotium #Espresso @Tom404_
  • 62. Robotium vs Espresso : Get ready to rumble ! Hamcrest Librairie de matchers #Droidcon #Robotium #Espresso @Tom404_
  • 63. Robotium vs Espresso : Get ready to rumble ! Hamcrest Librairie de matchers assertThat("Hello", equalTo("Hello")) #Droidcon #Robotium #Espresso @Tom404_
  • 64. Robotium vs Espresso : Get ready to rumble ! Hamcrest Librairie de matchers assertThat("Hello", equalTo("Hello")) ! // Sucre syntaxique assertThat(“Hello", is("Hello")) #Droidcon #Robotium #Espresso @Tom404_
  • 65. Robotium vs Espresso : Get ready to rumble ! Hamcrest Librairie de matchers assertThat("Hello", equalTo("Hello")) ! // Sucre syntaxique assertThat(“Hello", is("Hello")) ! // De nombreux matchers disponibles allOf not instanceOf hasProperty equalToIgnoringCase #Droidcon #Robotium #Espresso @Tom404_
  • 66. Robotium vs Espresso : Get ready to rumble ! Hamcrest Librairie de matchers assertThat("Hello", equalTo("Hello")) ! // Sucre syntaxique assertThat(“Hello", is("Hello")) ! // De nombreux matchers disponibles allOf not instanceOf hasProperty equalToIgnoringCase Possibilité de composition #Droidcon #Robotium #Espresso @Tom404_
  • 67. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 68. Robotium vs Espresso : Get ready to rumble ! Hamcrest custom matcher #Droidcon #Robotium #Espresso @Tom404_
  • 69. Robotium vs Espresso : Get ready to rumble ! Hamcrest custom matcher public class IsNotANumber extends TypeSafeMatcher<Double> { ! @Override public boolean matchesSafely(Double number) { return number.isNaN(); } ! public void describeTo(Description description) { description.appendText("not a number"); } ! public static Matcher<Double> notANumber() { return new IsNotANumber(); } ! } #Droidcon #Robotium #Espresso @Tom404_
  • 70. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 71. Robotium vs Espresso : Get ready to rumble ! API overview Espresso #Droidcon #Robotium #Espresso @Tom404_
  • 72. Robotium vs Espresso : Get ready to rumble ! API overview Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> #Droidcon #Robotium #Espresso @Tom404_
  • 73. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso withId()! onView(Matcher<View>)! onData(Matcher<Object> #Droidcon #Robotium #Espresso withText(text)! hasSibling(Matcher<View>) @Tom404_
  • 74. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> #Droidcon #Robotium #Espresso withId()! withText(text)! hasSibling(Matcher<View>) ViewActions click()! typeText(text) @Tom404_
  • 75. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> #Droidcon #Robotium #Espresso withId()! withText(text)! hasSibling(Matcher<View>) ViewActions click()! typeText(text) ViewAssertions doesNotExist()! matches(Matcher<View>) @Tom404_
  • 76. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> ViewInteraction / DataInteraction perform(ViewAction)! check(ViewAssertion) #Droidcon #Robotium #Espresso withId()! withText(text)! hasSibling(Matcher<View>) ViewActions click()! typeText(text) ViewAssertions doesNotExist()! matches(Matcher<View>) @Tom404_
  • 77. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> ViewInteraction / DataInteraction perform(ViewAction)! check(ViewAssertion) #Droidcon #Robotium #Espresso withId()! withText(text)! hasSibling(Matcher<View>) ViewActions click()! typeText(text) ViewAssertions doesNotExist()! matches(Matcher<View>) @Tom404_
  • 78. Robotium vs Espresso : Get ready to rumble ! API overview ViewMatchers Espresso Espresso onView(Matcher<View>)! onData(Matcher<Object> ViewInteraction / DataInteraction perform(ViewAction)! check(ViewAssertion) #Droidcon #Robotium #Espresso withId()! withText(text)! hasSibling(Matcher<View>) ViewActions click()! typeText(text) ViewAssertions doesNotExist()! matches(Matcher<View>) @Tom404_
  • 79. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 80. Robotium vs Espresso : Get ready to rumble ! Exemple #Droidcon #Robotium #Espresso @Tom404_
  • 81. Robotium vs Espresso : Get ready to rumble ! Exemple onView(allOf(withId(R.id.my_button), withText(“My Button”))) .check(matches(isDisplayed())) .perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 82. Robotium vs Espresso : Get ready to rumble ! Exemple onView(allOf(withId(R.id.my_button), withText(“My Button”))) .check(matches(isDisplayed())) .perform(click()); ! // Une simple extraction de méthode permet de simplifier onView(withIdAndText(R.id.my_button, "My Button”)) .check(matches(isDisplayed())) .perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 83. Robotium vs Espresso : Get ready to rumble ! Exemple onView(allOf(withId(R.id.my_button), withText(“My Button”))) .check(matches(isDisplayed())) .perform(click()); ! // Une simple extraction de méthode permet de simplifier onView(withIdAndText(R.id.my_button, "My Button”)) .check(matches(isDisplayed())) .perform(click()); ! // Si le bouton n'est pas affiché le perform(click()) échouera onView(withIdAndText(R.id.my_button, "My Button")).perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 84. Robotium vs Espresso : Get ready to rumble ! Exemple onView(allOf(withId(R.id.my_button), withText(“My Button”))) .check(matches(isDisplayed())) .perform(click()); ! // Une simple extraction de méthode permet de simplifier onView(withIdAndText(R.id.my_button, "My Button”)) .check(matches(isDisplayed())) .perform(click()); ! // Si le bouton n'est pas affiché le perform(click()) échouera onView(withIdAndText(R.id.my_button, "My Button")).perform(click()); Manque de restrictions = AmbiguousViewMatcherException #Droidcon #Robotium #Espresso @Tom404_
  • 85. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 86. Robotium vs Espresso : Get ready to rumble ! Listview #Droidcon #Robotium #Espresso @Tom404_
  • 87. Robotium vs Espresso : Get ready to rumble ! Listview Robotium // Clic sur item solo.clickOnText("textToFind"); ! // Si jamais il y'en a plusieurs -> utilisation d'un index solo.clickOnText("textToFind", 3); ! // Ou choisir directement la ligne solo.clickInList(2); #Droidcon #Robotium #Espresso @Tom404_
  • 88. Robotium vs Espresso : Get ready to rumble ! Listview Espresso onData(allOf(is(instanceOf(String.class)), is("textToFind"))).perform(click()); ! // Ou directement à une position onData(is(instanceOf(String.class))).atPosition(0).perform(click()); ! // Possibilité de préciser une listview, utile pour le view pager onData(allOf(is(instanceOf(String.class)), is("textToFind"))) .inAdapterView(withId(R.id.my_list)).perform(click()); ! // Interaction avec une vue enfant de la ligne onData(allOf(is(instanceOf(String.class)), is("textToFind"))) .onChildView(withId(R.id.my_child)) .perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 89. Robotium vs Espresso : Get ready to rumble ! Listview Espresso : cas plus complexe // Type renvoyé par la méthode getItem de l'adapteur public class Item { public String name; public String itemContent; } ! onData(allOf(is(instanceOf(Item.class)), hasProperty(“name", equalTo(“nameToFind")))) .perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 90. Robotium vs Espresso : Get ready to rumble ! Listview Espresso : custom matcher public static Matcher<Object> withItemName(final Matcher<String> itemTextMatcher){ return new BoundedMatcher<Object, Item>(Item.class) { @Override public boolean matchesSafely(Item item) { return itemTextMatcher.matches(item.name); } ! @Override public void describeTo(Description description) { description.appendText("with item name: "); itemTextMatcher.describeTo(description); } }; } onData(withItemName(equalTo("nameToFind"))).perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 91. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 92. Robotium vs Espresso : Get ready to rumble ! Webview Robotium #Droidcon #Robotium #Espresso @Tom404_
  • 93. Robotium vs Espresso : Get ready to rumble ! Webview Robotium Possibilité d’interagir avec les webviews •solo.getWebElements(by) •solo.clickOnWebElement(by) #Droidcon #Robotium #Espresso @Tom404_
  • 94. Robotium vs Espresso : Get ready to rumble ! Webview Robotium Possibilité d’interagir avec les webviews •solo.getWebElements(by) •solo.clickOnWebElement(by) Plusieurs types de recherches disponibles •By.id(String id) •By.className(String className) •By.textContent(String textContent) •By.name(String name) #Droidcon #Robotium #Espresso @Tom404_
  • 95. Robotium vs Espresso : Get ready to rumble ! Webview Espresso #Droidcon #Robotium #Espresso @Tom404_
  • 96. Robotium vs Espresso : Get ready to rumble ! Webview Espresso #Droidcon #Robotium #Espresso @Tom404_
  • 97. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 98. Robotium vs Espresso : Get ready to rumble ! Navigation Drawer #Droidcon #Robotium #Espresso @Tom404_
  • 99. Robotium vs Espresso : Get ready to rumble ! Navigation Drawer Robotium // Attention l'id du frame layout du menu doit absolument être "left_drawer" solo.setNavigationDrawer(Solo.OPENED); ! solo.setNavigationDrawer(Solo.CLOSED); #Droidcon #Robotium #Espresso @Tom404_
  • 100. Robotium vs Espresso : Get ready to rumble ! Navigation Drawer Robotium // Attention l'id du frame layout du menu doit absolument être "left_drawer" solo.setNavigationDrawer(Solo.OPENED); ! solo.setNavigationDrawer(Solo.CLOSED); Espresso DrawerActions.openDrawer(R.id.drawer_layout); ! DrawerActions.closeDrawer(R.id.drawer_layout); #Droidcon #Robotium #Espresso @Tom404_
  • 101. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 102. Robotium vs Espresso : Get ready to rumble ! Action bar #Droidcon #Robotium #Espresso @Tom404_
  • 103. Robotium vs Espresso : Get ready to rumble ! Action bar Robotium solo.clickOnActionBarItem(R.id.action_example); ! // Cas de l'action bar overflow solo.sendKey(KeyEvent.KEYCODE_MENU); solo.clickOnText("action"); #Droidcon #Robotium #Espresso @Tom404_
  • 104. Robotium vs Espresso : Get ready to rumble ! Action bar Robotium solo.clickOnActionBarItem(R.id.action_example); ! // Cas de l'action bar overflow solo.sendKey(KeyEvent.KEYCODE_MENU); solo.clickOnText("action"); Espresso onView(withId(R.id_action_example)).perform(click()); ! // Cas de l'action bar overflow openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); onView(withText("action")).perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 105. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 106. Robotium vs Espresso : Get ready to rumble ! Back button & Keyboard #Droidcon #Robotium #Espresso @Tom404_
  • 107. Robotium vs Espresso : Get ready to rumble ! Back button & Keyboard Robotium solo.goBack(); // solo.goBack() est aussi utilisé pour fermer le clavier #Droidcon #Robotium #Espresso @Tom404_
  • 108. Robotium vs Espresso : Get ready to rumble ! Back button & Keyboard Robotium solo.goBack(); // solo.goBack() est aussi utilisé pour fermer le clavier Espresso Espresso.pressBack(); Espresso.closeSoftKeyboard(); #Droidcon #Robotium #Espresso @Tom404_
  • 109. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 110. Robotium vs Espresso : Get ready to rumble ! Les messages d’erreur #Droidcon #Robotium #Espresso @Tom404_
  • 111. Robotium vs Espresso : Get ready to rumble ! Les messages d’erreur Robotium ! // Récupération d’une vue inexistante solo.getView(1234); !j unit.framework.AssertionFailedError: View with id: '1234' is not found! at com.robotium.solo.Solo.getView(Solo.java:2008) at com.robotium.solo.Solo.getView(Solo.java:1988) at fr.droidcon.robotium.vs.espresso.samples.test.robotium.SimpleActionsTest.testClickButton(SimpleAct ionsTest.java:28) #Droidcon #Robotium #Espresso @Tom404_
  • 112. Robotium vs Espresso : Get ready to rumble ! Les messages d’erreur Espresso ! // Récupération d’une vue inexistante onView(withId(1234)); com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: is <1234> If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it from one of the following AdapterViews:android.widget.ListView{426f6f18 VFED.VC. ......ID 0,0-720,1557} - android.widget.ListView{4269c598 V.ED.VC. ........ 48,393-1032,1509 #7f070042 app:id/my_list} ! View Hierarchy: +>DecorView{id=-1, visibility=VISIBLE, width=1080, height=1776, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout- requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1} | +->ActionBarOverlayLayout{id=16909075, res-name=action_bar_overlay_layout, visibility=VISIBLE, width=1080, height=1776, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable= false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected= false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count= 3} | +-->FrameLayout{id=16908290, res-name=content, visibility=VISIBLE, width=1080, height=1557, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is- #Droidcon #Robotium #Espresso @Tom404_
  • 115. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 116. Robotium vs Espresso : Get ready to rumble ! Wait and See #Droidcon #Robotium #Espresso @Tom404_
  • 117. Robotium vs Espresso : Get ready to rumble ! Wait and See Robotium repose sur le principe de wait & see •solo.waitForActivity(Class class, int timeout) • solo.waitForCondition(Condition condition, int timeout) • solo.waitForDialogToOpen() #Droidcon #Robotium #Espresso @Tom404_
  • 118. Robotium vs Espresso : Get ready to rumble ! Wait and See Robotium repose sur le principe de wait & see •solo.waitForActivity(Class class, int timeout) • solo.waitForCondition(Condition condition, int timeout) • solo.waitForDialogToOpen() solo.clickOnView(R.id.start_activity_button); ! // On attend que la vue apparaisse avant d'agir solo.waitForView(R.id.view_in_new_activity); ! solo.clickOnView(R.id.view_in_new_activity); #Droidcon #Robotium #Espresso @Tom404_
  • 119. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 120. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! #Droidcon #Robotium #Espresso @Tom404_
  • 121. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! Entrée en jeu du GoogleInstrumentationTestRunner #Droidcon #Robotium #Espresso @Tom404_
  • 122. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! Entrée en jeu du GoogleInstrumentationTestRunner Monitoring plus fin des activités et des ressources #Droidcon #Robotium #Espresso @Tom404_
  • 123. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! Entrée en jeu du GoogleInstrumentationTestRunner Monitoring plus fin des activités et des ressources Analyse du ThreadUI pour savoir quand agir #Droidcon #Robotium #Espresso @Tom404_
  • 124. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! Entrée en jeu du GoogleInstrumentationTestRunner Monitoring plus fin des activités et des ressources Analyse du ThreadUI pour savoir quand agir Pas de wait #Droidcon #Robotium #Espresso @Tom404_
  • 125. Robotium vs Espresso : Get ready to rumble ! Finis de dormir ! Entrée en jeu du GoogleInstrumentationTestRunner Monitoring plus fin des activités et des ressources Analyse du ThreadUI pour savoir quand agir Pas de wait onView(withId(R.id.start_activity_button)).perform(click()); ! onView(withId(R.id.view_in_new_activity)).perform(click()); #Droidcon #Robotium #Espresso @Tom404_
  • 126. Robotium vs Espresso : Get ready to rumble ! #Droidcon #Robotium #Espresso @Tom404_
  • 127. Robotium vs Espresso : Get ready to rumble ! Idle mais actif ! #Droidcon #Robotium #Espresso @Tom404_
  • 128. Robotium vs Espresso : Get ready to rumble ! Idle mais actif ! Possibilité d'enregistrer des idlingResources #Droidcon #Robotium #Espresso @Tom404_
  • 129. Robotium vs Espresso : Get ready to rumble ! class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource { private int threadCount = 0; private ResourceCallback resourceCallback; ... @Override public synchronized void execute(Runnable r) { threadCount++; super.execute(r); } @Override public synchronized boolean isIdleNow() { return threadCount == 0; } @Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { this.resourceCallback = resourceCallback; } @Override protected synchronized void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); threadCount--; if (resourceCallback != null && isIdleNow()) { resourceCallback.onTransitionToIdle(); } } } #Droidcon #Robotium #Espresso @Tom404_
  • 130. Robotium vs Espresso : Get ready to rumble ! class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource { private int threadCount = 0; private ResourceCallback resourceCallback; ... @Override public synchronized void execute(Runnable r) { threadCount++; super.execute(r); } @Override public synchronized boolean isIdleNow() { return threadCount == 0; } @Override public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { this.resourceCallback = resourceCallback; } @Override protected synchronized void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); threadCount--; if (resourceCallback != null && isIdleNow()) { resourceCallback.onTransitionToIdle(); } } } Espresso.registerIdlingResources(espressoThreadPool); #Droidcon #Robotium #Espresso @Tom404_