Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014

Click here to load reader

  • date post

    13-Jun-2015
  • Category

    Technology

  • view

    1.328
  • download

    5

Embed Size (px)

description

http://fr.droidcon.com/2014/agenda http://fr.droidcon.com/2014/agenda/detail?title=Robotium+vs+Espresso%3A+Get+ready+to+rumble+! Ladies and gentlemen, boys and girls. Dans le coin rouge, accusant un poids de 104KB, le plus populaire de tous les frameworks de test: Robotium. Dans le coin bleu, avec un poids de 262KB et le support des équipes Google, celui qu’on qualifie de “new comer” : Espresso. Que le match commence !! Au programme nous verrons avec du code le fonctionnement de ces bibliothèques, leurs avantages mais aussi leurs inconvénients. Nous y parlerons également de Calabash Android et de UI Automator. Speaker : Thomas Guerin, Xebia Thomas Guerin est consultant pour Xebia depuis 2011. Passionné de développement Android et adepte des bonnes pratiques de développement, il s'intéresse de près au déploiement continu sur mobile.

Transcript of Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014

  • 1. Robotiumvs EspressoGet ready to rumble !

2. Thomas Guerin 3. Thomas GuerinDveloppeur Android 4. Thomas GuerinDveloppeur AndroidTests addict 5. Thomas GuerinDveloppeur AndroidTests addictNiveau 15 Destiny 6. Robotium vs Espresso : Get ready to rumble ! 7. Robotium vs Espresso : Get ready to rumble !Pourquoi ne pas faire de tests ?#Droidcon #Robotium #Espresso @Tom404_ 8. Robotium vs Espresso : Get ready to rumble !Pourquoi ne pas faire de tests ?Mes tests durent des heures !#Droidcon #Robotium #Espresso @Tom404_ 9. Robotium vs Espresso : Get ready to rumble !Pourquoi ne pas faire de tests ?Mes tests durent des heures !Tester ce nest pas toujours simple !#Droidcon #Robotium #[email protected]_ 10. Robotium vs Espresso : Get ready to rumble !Pourquoi ne pas faire de tests ?Mes tests durent des heures !Tester ce nest pas toujours simple !Mes tests chouent alatoirement !#Droidcon #Robotium #[email protected]_ 11. Robotium vs Espresso : Get ready to rumble !Pourquoi ne pas faire de tests ?Mes tests durent des heures !Tester ce nest pas toujours simple !Mes tests chouent alatoirement !Je vais devoir corriger les tests alors que jenai presque rien modifi#Droidcon #Robotium #[email protected]_ 12. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 13. Robotium vs Espresso : Get ready to rumble !Un test doit tre#Droidcon #Robotium #Espresso @Tom404_ 14. Robotium vs Espresso : Get ready to rumble !Un test doit treSimple#Droidcon #Robotium #[email protected]_ 15. Robotium vs Espresso : Get ready to rumble !Un test doit treSimple Rapide#Droidcon #Robotium #[email protected]_ 16. Robotium vs Espresso : Get ready to rumble !Un test doit treSimple Rapide Fiable#Droidcon #Robotium #[email protected]_ 17. Robotium vs Espresso : Get ready to rumble !Un test doit treSimple Rapide Fiable Durable#Droidcon #Robotium #[email protected]_ 18. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 19. Robotium vs Espresso : Get ready to rumble !Un mauvais exemple#Droidcon #Robotium #Espresso @Tom404_ 20. Robotium vs Espresso : Get ready to rumble !Un mauvais exemple// Start the main activity of the application under testmActivity = getActivity();!// Get a handle to the Activity object's main UI widget, a SpinnermSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);!// Set the Spinner to a known positionmActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);!// Stop the activity - The onDestroy() method should save the state of the SpinnermActivity.finish();!// Re-start the Activity - the onResume() method should restore the state of the SpinnermActivity = getActivity();!// Get the Spinner's current positionint currentPosition = mActivity.getSpinnerPosition();!// Assert that the current position is the same as the starting positionassertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);#Droidcon #Robotium #[email protected]_ 21. Robotium vs Espresso : Get ready to rumble !Un mauvais exemple// Start the main activity of the application under testmActivity = getActivity();!// Get a handle to the Activity object's main UI widget, a SpinnermSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);!// Set the Spinner to a known positionmActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);!// Stop the activity - The onDestroy() method should save the state of the SpinnermActivity.finish();!// Re-start the Activity - the onResume() method should restore the state of the SpinnermActivity = getActivity();!// Get the Spinner's current positionint currentPosition = mActivity.getSpinnerPosition();!// Assert that the current position is the same as the starting positionassertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);#Droidcon #Robotium #[email protected]_ 22. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 23. Robotium vs Espresso : Get ready to rumble !Les combattants#Droidcon #Robotium #Espresso @Tom404_ 24. Robotium vs Espresso : Get ready to rumble !Les combattantsRobotium#Droidcon #Robotium #[email protected]_ 25. Robotium vs Espresso : Get ready to rumble !Les combattants#Droidcon #Robotium #EspressoVSRobotium [email protected]_ 26. Prparation 27. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 28. Robotium vs Espresso : Get ready to rumble !Dpendances Gradle#Droidcon #Robotium #Espresso @Tom404_ 29. Robotium vs Espresso : Get ready to rumble !Dpendances GradleRobotiumdependencies {androidTestCompile com.jayway.android.robotium:robotium-solo:5.2.1'androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'}#Droidcon #Robotium #[email protected]_ 30. Robotium vs Espresso : Get ready to rumble !Dpendances GradleEspressodependencies {/* Jars rcuprs 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 #[email protected]_ 31. Robotium vs Espresso : Get ready to rumble !Dpendances GradleDouble Espressodependencies {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 #[email protected]_ 32. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 33. Robotium vs Espresso : Get ready to rumble !Test Runner#Droidcon #Robotium #Espresso @Tom404_ 34. Robotium vs Espresso : Get ready to rumble !Test RunnerRobotium utilise le test runner du sdk#Droidcon #Robotium #[email protected]_ 35. Robotium vs Espresso : Get ready to rumble !Test RunnerRobotium utilise le test runner du sdkEspresso ncessite un test runner spcifique#Droidcon #Robotium #[email protected]_ 36. Robotium vs Espresso : Get ready to rumble !Test RunnerRobotium utilise le test runner du sdkEspresso ncessite un test runner spcifiquedefaultConfig {testInstrumentationRunner"com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner"}#Droidcon #Robotium #[email protected]_ 37. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 38. Robotium vs Espresso : Get ready to rumble !GoogleInstrumentationTestRunner#Droidcon #Robotium #Espresso @Tom404_ 39. Robotium vs Espresso : Get ready to rumble !GoogleInstrumentationTestRunneronCreate de l'application finalise avant le dbut des tests#Droidcon #Robotium #[email protected]_ 40. Robotium vs Espresso : Get ready to rumble !GoogleInstrumentationTestRunneronCreate de l'application finalise avant le dbut des testsInstrumentation termine == activits finies#Droidcon #Robotium #[email protected]_ 41. Robotium vs Espresso : Get ready to rumble !GoogleInstrumentationTestRunneronCreate de l'application finalise avant le dbut des testsInstrumentation termine == activits finiesMonitoring des activits plus fiable#Droidcon #Robotium #[email protected]_ 42. Robotium vs Espresso : Get ready to rumble !GoogleInstrumentationTestRunneronCreate de l'application finalise avant le dbut des testsInstrumentation termine == activits finiesMonitoring des activits plus fiablePeut tre utilis avec d'autres librairies#Droidcon #Robotium #[email protected]_ 43. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 44. Robotium vs Espresso : Get ready to rumble !Initialisation#Droidcon #Robotium #Espresso @Tom404_ 45. Robotium vs Espresso : Get ready to rumble !InitialisationRobotiumpublic class SimpleActionsTest extends ActivityInstrumentationTestCase2 {!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 #[email protected]_ 46. Robotium vs Espresso : Get ready to rumble !InitialisationEspressopublic class SimpleActionsTest extends ActivityInstrumentationTestCase2 {[email protected] void setUp() throws Exception {super.setUp();// Espresso ne va pas lancer l'activit pour nousgetActivity();}}#Droidcon #Robotium #[email protected]_ 47. Expressivit 48. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 49. Robotium vs Espresso : Get ready to rumble !API overviewRobotium#Droidcon #Robotium #[email protected]_ 50. Robotium vs Espresso : Get ready to rumble !API overview#Droidcon #Robotium #[email protected]_ 51. Robotium vs Espresso : Get ready to rumble !API overviewclickOnActionBarHome()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 #EspressoSologetView(int viewId)drag()clickInList(int line, int index)goBack()setNavigationDrawer(int status)clickOnActionBarItem(int id)getButton(int index)scrollToBottom() searchEditText(String text)pressSoftKeyboardSearchButton()@Tom404_ 52. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 53. Robotium vs Espresso : Get ready to rumble !Exemple#Droidcon #Robotium #Espresso @Tom404_ 54. Robotium vs Espresso : Get ready to rumble !Exemple// Rcupration de la vueButton myButton = (TextView) solo.getView(R.id.my_button);!// Assertions (AssertJ Android)assertThat(myButton).hasText(My button).isVisible();!// Clic sur la vuesolo.clickOnView(myButton)#Droidcon #Robotium #[email protected]_ 55. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 56. Robotium vs Espresso : Get ready to rumble !Hamcrest#Droidcon #Robotium #Espresso @Tom404_ 57. Robotium vs Espresso : Get ready to rumble !HamcrestLibrairie de matchers#Droidcon #Robotium #[email protected]_ 58. Robotium vs Espresso : Get ready to rumble !HamcrestLibrairie de matchersassertThat("Hello", equalTo("Hello"))#Droidcon #Robotium #[email protected]_ 59. Robotium vs Espresso : Get ready to rumble !HamcrestLibrairie de matchersassertThat("Hello", equalTo("Hello"))!// Sucre syntaxiqueassertThat(Hello", is("Hello"))#Droidcon #Robotium #[email protected]_ 60. Robotium vs Espresso : Get ready to rumble !HamcrestLibrairie de matchersassertThat("Hello", equalTo("Hello"))!// Sucre syntaxiqueassertThat(Hello", is("Hello"))!// De nombreux matchers disponiblesallOf not instanceOf hasProperty equalToIgnoringCase#Droidcon #Robotium #[email protected]_ 61. Robotium vs Espresso : Get ready to rumble !HamcrestLibrairie de matchersassertThat("Hello", equalTo("Hello"))!// Sucre syntaxiqueassertThat(Hello", is("Hello"))!// De nombreux matchers disponiblesallOf not instanceOf hasProperty equalToIgnoringCasePossibilit de composition#Droidcon #Robotium #[email protected]_ 62. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 63. Robotium vs Espresso : Get ready to rumble !Hamcrest custom matcher#Droidcon #Robotium #Espresso @Tom404_ 64. Robotium vs Espresso : Get ready to rumble !Hamcrest custom matcherpublic class IsNotANumber extends TypeSafeMatcher {[email protected] boolean matchesSafely(Double number) {return number.isNaN();}!public void describeTo(Description description) {description.appendText("not a number");}!public static Matcher notANumber() {return new IsNotANumber();}!}#Droidcon #Robotium #[email protected]_ 65. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 66. Robotium vs Espresso : Get ready to rumble !API overviewEspresso#Droidcon #Robotium #[email protected]_ 67. Robotium vs Espresso : Get ready to rumble !API overviewEspressoEspressoonView(Matcher)!onData(Matcher#Droidcon #Robotium #[email protected]_ 68. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspresso withId()!onView(Matcher)!onData(Matcher#Droidcon #Robotium #EspressowithText(text)!hasSibling(Matcher)@Tom404_ 69. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspressoonView(Matcher)!onData(Matcher#Droidcon #Robotium #EspressowithId()!withText(text)!hasSibling(Matcher)ViewActionsclick()!typeText(text)@Tom404_ 70. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspressoonView(Matcher)!onData(Matcher#Droidcon #Robotium #EspressowithId()!withText(text)!hasSibling(Matcher)ViewActionsclick()!typeText(text)ViewAssertionsdoesNotExist()!matches(Matcher)@Tom404_ 71. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspressoonView(Matcher)!onData(MatcherViewInteraction / DataInteractionperform(ViewAction)!check(ViewAssertion)#Droidcon #Robotium #EspressowithId()!withText(text)!hasSibling(Matcher)ViewActionsclick()!typeText(text)ViewAssertionsdoesNotExist()!matches(Matcher)@Tom404_ 72. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspressoonView(Matcher)!onData(MatcherViewInteraction / DataInteractionperform(ViewAction)!check(ViewAssertion)#Droidcon #Robotium #EspressowithId()!withText(text)!hasSibling(Matcher)ViewActionsclick()!typeText(text)ViewAssertionsdoesNotExist()!matches(Matcher)@Tom404_ 73. Robotium vs Espresso : Get ready to rumble !API overviewViewMatchers EspressoEspressoonView(Matcher)!onData(MatcherViewInteraction / DataInteractionperform(ViewAction)!check(ViewAssertion)#Droidcon #Robotium #EspressowithId()!withText(text)!hasSibling(Matcher)ViewActionsclick()!typeText(text)ViewAssertionsdoesNotExist()!matches(Matcher)@Tom404_ 74. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 75. Robotium vs Espresso : Get ready to rumble !Exemple#Droidcon #Robotium #Espresso @Tom404_ 76. Robotium vs Espresso : Get ready to rumble !ExempleonView(allOf(withId(R.id.my_button), withText(My Button))).check(matches(isDisplayed())).perform(click());#Droidcon #Robotium #[email protected]_ 77. Robotium vs Espresso : Get ready to rumble !ExempleonView(allOf(withId(R.id.my_button), withText(My Button))).check(matches(isDisplayed())).perform(click());!// Une simple extraction de mthode permet de simplifieronView(withIdAndText(R.id.my_button, "My Button)).check(matches(isDisplayed())).perform(click());#Droidcon #Robotium #[email protected]_ 78. Robotium vs Espresso : Get ready to rumble !ExempleonView(allOf(withId(R.id.my_button), withText(My Button))).check(matches(isDisplayed())).perform(click());!// Une simple extraction de mthode permet de simplifieronView(withIdAndText(R.id.my_button, "My Button)).check(matches(isDisplayed())).perform(click());!// Si le bouton n'est pas affich le perform(click()) choueraonView(withIdAndText(R.id.my_button, "My Button")).perform(click());#Droidcon #Robotium #[email protected]_ 79. Robotium vs Espresso : Get ready to rumble !ExempleonView(allOf(withId(R.id.my_button), withText(My Button))).check(matches(isDisplayed())).perform(click());!// Une simple extraction de mthode permet de simplifieronView(withIdAndText(R.id.my_button, "My Button)).check(matches(isDisplayed())).perform(click());!// Si le bouton n'est pas affich le perform(click()) choueraonView(withIdAndText(R.id.my_button, "My Button")).perform(click());Manque de restrictions = AmbiguousViewMatcherException#Droidcon #Robotium #[email protected]_ 80. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 81. Robotium vs Espresso : Get ready to rumble !Listview#Droidcon #Robotium #Espresso @Tom404_ 82. Robotium vs Espresso : Get ready to rumble !ListviewRobotium// Clic sur itemsolo.clickOnText("textToFind");!// Si jamais il y'en a plusieurs -> utilisation d'un indexsolo.clickOnText("textToFind", 3);!// Ou choisir directement la lignesolo.clickInList(2);#Droidcon #Robotium #[email protected]_ 83. Robotium vs Espresso : Get ready to rumble !ListviewEspressoonData(allOf(is(instanceOf(String.class)), is("textToFind"))).perform(click());!// Ou directement une positiononData(is(instanceOf(String.class))).atPosition(0).perform(click());!// Possibilit de prciser une listview, utile pour le view pageronData(allOf(is(instanceOf(String.class)), is("textToFind"))).inAdapterView(withId(R.id.my_list)).perform(click());!// Interaction avec une vue enfant de la ligneonData(allOf(is(instanceOf(String.class)), is("textToFind"))).onChildView(withId(R.id.my_child)).perform(click());#Droidcon #Robotium #[email protected]_ 84. Robotium vs Espresso : Get ready to rumble !ListviewEspresso : cas plus complexe// Type renvoy par la mthode getItem de l'adapteurpublic class Item {public String name;public String itemContent;}!onData(allOf(is(instanceOf(Item.class)), hasProperty(name", equalTo(nameToFind")))).perform(click());#Droidcon #Robotium #[email protected]_ 85. Robotium vs Espresso : Get ready to rumble !ListviewEspresso : custom matcherpublic static Matcher withItemName(final Matcher itemTextMatcher){return new BoundedMatcher(Item.class) {@Overridepublic boolean matchesSafely(Item item) {return itemTextMatcher.matches(item.name);}[email protected] void describeTo(Description description) {description.appendText("with item name: ");itemTextMatcher.describeTo(description);}};}onData(withItemName(equalTo("nameToFind"))).perform(click());#Droidcon #Robotium #[email protected]_ 86. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 87. Robotium vs Espresso : Get ready to rumble !WebviewRobotium#Droidcon #Robotium #[email protected]_ 88. Robotium vs Espresso : Get ready to rumble !WebviewRobotiumPossibilit dinteragir avec les webviewssolo.getWebElements(by)solo.clickOnWebElement(by)#Droidcon #Robotium #[email protected]_ 89. Robotium vs Espresso : Get ready to rumble !WebviewRobotiumPossibilit dinteragir avec les webviewssolo.getWebElements(by)solo.clickOnWebElement(by)Plusieurs types de recherches disponiblesBy.id(String id)By.className(String className)By.textContent(String textContent)By.name(String name)#Droidcon #Robotium #[email protected]_ 90. Robotium vs Espresso : Get ready to rumble !WebviewEspresso#Droidcon #Robotium #[email protected]04_ 91. Robotium vs Espresso : Get ready to rumble !WebviewEspresso#Droidcon #Robotium #[email protected]_ 92. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 93. Robotium vs Espresso : Get ready to rumble !Navigation Drawer#Droidcon #Robotium #Espresso @Tom404_ 94. Robotium vs Espresso : Get ready to rumble !Navigation DrawerRobotium// Attention l'id du frame layout du menu doit absolument tre "left_drawer"solo.setNavigationDrawer(Solo.OPENED);!solo.setNavigationDrawer(Solo.CLOSED);#Droidcon #Robotium #[email protected]_ 95. Robotium vs Espresso : Get ready to rumble !Navigation DrawerRobotium// Attention l'id du frame layout du menu doit absolument tre "left_drawer"solo.setNavigationDrawer(Solo.OPENED);!solo.setNavigationDrawer(Solo.CLOSED);EspressoDrawerActions.openDrawer(R.id.drawer_layout);!DrawerActions.closeDrawer(R.id.drawer_layout);#Droidcon #Robotium #[email protected]_ 96. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 97. Robotium vs Espresso : Get ready to rumble !Action bar#Droidcon #Robotium #Espresso @Tom404_ 98. Robotium vs Espresso : Get ready to rumble !Action barRobotiumsolo.clickOnActionBarItem(R.id.action_example);!// Cas de l'action bar overflowsolo.sendKey(KeyEvent.KEYCODE_MENU);solo.clickOnText("action");#Droidcon #Robotium #[email protected]_ 99. Robotium vs Espresso : Get ready to rumble !Action barRobotiumsolo.clickOnActionBarItem(R.id.action_example);!// Cas de l'action bar overflowsolo.sendKey(KeyEvent.KEYCODE_MENU);solo.clickOnText("action");EspressoonView(withId(R.id_action_example)).perform(click());!// Cas de l'action bar overflowopenActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());onView(withText("action")).perform(click());#Droidcon #Robotium #[email protected]_ 100. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 101. Robotium vs Espresso : Get ready to rumble !Back button & Keyboard#Droidcon #Robotium #Espresso @Tom404_ 102. Robotium vs Espresso : Get ready to rumble !Back button & KeyboardRobotiumsolo.goBack();// solo.goBack() est aussi utilis pour fermer le clavier#Droidcon #Robotium #[email protected]_ 103. Robotium vs Espresso : Get ready to rumble !Back button & KeyboardRobotiumsolo.goBack();// solo.goBack() est aussi utilis pour fermer le clavierEspressoEspresso.pressBack();Espresso.closeSoftKeyboard();#Droidcon #Robotium #[email protected]_ 104. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 105. Robotium vs Espresso : Get ready to rumble !Les messages derreur#Droidcon #Robotium #Espresso @Tom404_ 106. Robotium vs Espresso : Get ready to rumble !Les messages derreurRobotium!// Rcupration dune vue inexistantesolo.getView(1234);!junit.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)atfr.droidcon.robotium.vs.espresso.samples.test.robotium.SimpleActionsTest.testClickButton(SimpleActionsTest.java:28)#Droidcon #Robotium #Espresso @Tom404_ 107. Robotium vs Espresso : Get ready to rumble !Les messages derreurEspresso!// Rcupration dune vue inexistanteonView(withId(1234));com.google.android.apps.common.testing.ui.espresso.NoMatchingViewException: No views in hierarchyfound matching: with id: is If the target view is not part of the view hierarchy, you may need to use Espresso.onData to load it fromone 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_ 108. Enchanements 109. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 110. Robotium vs Espresso : Get ready to rumble !Wait and See#Droidcon #Robotium #Espresso @Tom404_ 111. Robotium vs Espresso : Get ready to rumble !Wait and SeeRobotium repose sur le principe de wait & seesolo.waitForActivity(Class class, int timeout) solo.waitForCondition(Condition condition, int timeout) solo.waitForDialogToOpen()#Droidcon #Robotium #[email protected]_ 112. Robotium vs Espresso : Get ready to rumble !Wait and SeeRobotium repose sur le principe de wait & seesolo.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'agirsolo.waitForView(R.id.view_in_new_activity);!solo.clickOnView(R.id.view_in_new_activity);#Droidcon #Robotium #[email protected]_ 113. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 114. Robotium vs Espresso : Get ready to rumble !Finis de dormir !#Droidcon #Robotium #Espresso @Tom404_ 115. Robotium vs Espresso : Get ready to rumble !Finis de dormir !Entre en jeu du GoogleInstrumentationTestRunner#Droidcon #Robotium #[email protected]_ 116. Robotium vs Espresso : Get ready to rumble !Finis de dormir !Entre en jeu du GoogleInstrumentationTestRunnerMonitoring plus fin des activits et des ressources#Droidcon #Robotium #[email protected]_ 117. Robotium vs Espresso : Get ready to rumble !Finis de dormir !Entre en jeu du GoogleInstrumentationTestRunnerMonitoring plus fin des activits et des ressourcesAnalyse du ThreadUI pour savoir quand agir#Droidcon #Robotium #[email protected]_ 118. Robotium vs Espresso : Get ready to rumble !Finis de dormir !Entre en jeu du GoogleInstrumentationTestRunnerMonitoring plus fin des activits et des ressourcesAnalyse du ThreadUI pour savoir quand agirPas de wait#Droidcon #Robotium #[email protected]_ 119. Robotium vs Espresso : Get ready to rumble !Finis de dormir !Entre en jeu du GoogleInstrumentationTestRunnerMonitoring plus fin des activits et des ressourcesAnalyse du ThreadUI pour savoir quand agirPas de waitonView(withId(R.id.start_activity_button)).perform(click());!onView(withId(R.id.view_in_new_activity)).perform(click());#Droidcon #Robotium #[email protected]_ 120. Robotium vs Espresso : Get ready to rumble !#Droidcon #Robotium #Espresso @Tom404_ 121. Robotium vs Espresso : Get ready to rumble !Idle mais actif !#Droidcon #Robotium #Espresso @Tom404_ 122. Robotium vs Espresso : Get ready to rumble !Idle mais actif !Possibilit d'enregistrer des idlingResources#Droidcon #Robotium #[email protected]_ 123. Robotium vs Espresso : Get ready to rumble !class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource {private int threadCount = 0;private ResourceCallback resourceCallback;[email protected] synchronized void execute(Runnable r) {threadCount++;super.execute(r);}@Overridepublic synchronized boolean isIdleNow() {return threadCount == 0;}@Overridepublic void registerIdleTransitionCallback(ResourceCallback resourceCallback) {this.resourceCallback = resourceCallback;}@Overrideprotected synchronized void afterExecute(Runnable r, Throwable t) {super.afterExecute(r, t);threadCount--;if (resourceCallback != null && isIdleNow()) {resourceCallback.onTransitionToIdle();}}}#Droidcon #Robotium #[email protected]_ 124. Robotium vs Espresso : Get ready to rumble !class EspressoThreadPool extends ThreadPoolExecutor implements IdlingResource {private int threadCount = 0;private ResourceCallback resourceCallback;[email protected] synchronized void execute(Runnable r) {threadCount++;super.execute(r);}@Overridepublic synchronized boolean isIdleNow() {return threadCount == 0;}@Overridepublic void registerIdleTransitionCallback(ResourceCallback resourceCallback) {this.resourceCallback = resourceCallback;}@Overrideprotected synchronized void afterExecute(Runnable r, Throwable t) {super.afterExecute(r, t);threadCount--;if (resourceCallback != null && isIdleNow()) {resourceCallback.onTransitionToIdle();}}}Espresso.registerIdlingResources(espressoThreadPool);#Droidcon #Robotium #[email protected]_ 125. Conclusion 126. Questions ?