Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Discovering Android Testing

Discovering Android Testing

Slides for the presentation about Android Testing that i gave for the Pucela Testing Days

Mario de Frutos

November 30, 2013
Tweet

Other Decks in Programming

Transcript

  1. What is it? A unit test is an automated piece

    of code that invokes a unit of work in the system and then checks a single assumption about the behavior of that unit of work. - The art of unit testing What are we going to test in Android? Business Logic View validation Behavior sábado, 30 de noviembre de 13
  2. Business Logic ‣Better if you make it independent from the

    Android platform ‣Possible to test using JUnit3 ‣Example sábado, 30 de noviembre de 13
  3. View validation ‣Mainly check the view elements are correctly displayed

    View Behavior ‣Check that the view behavior is the expected ¿EXAMPLES?? sábado, 30 de noviembre de 13
  4. Test What type of test should i use? Use only

    the JVM Use Android FW LET’S TRY WITH JUNIT alone... sábado, 30 de noviembre de 13
  5. Let’s try ActivityUnitTestCase [ERROR] Failed to execute goal com.jayway.maven.plugins.android.generation2:android-maven-plugin: 3.8.0:internal-pre-integration-test

    (default-internal-pre-integration-test) on project pucelatestingapptest: No online devices attached. @Override        protected  void  setUp()  throws  Exception  {                super.setUp();                Intent  intent  =  new  Intent(getInstrumentation().getTargetContext(),                                MainActivity.class);                startActivity(intent,  null,  null);                activity  =  getActivity();        }        public  void  testRadioOfEurIsMarkedByDefault()  {                RadioButton  radioEurs  =  (RadioButton)  activity.findViewById(R.id.eurs_radio_button);                assertTrue("Eur  radio  button  not  marked  by  default",  radioEurs.isChecked());        } sábado, 30 de noviembre de 13
  6. What is Robolectric? Robolectric is a unit test framework that

    de-fangs the Android SDK jar so you can test- drive the development of your Android app ‣Rewrite the Android SDK classes to be able to load in the JVM ‣Can use resources, themes, etc ‣Use Shadow Objects a.k.a Proxies: 1. Intercept of loading Android SUT 2. Rewrite the body 3. Bind “shadow object” to the new Android object ‣ Is possible to build your own shadow objects sábado, 30 de noviembre de 13
  7. @RunWith(RobolectricTestRunner.class) public  class  MainActivityRobolectricTest  {        private  MainActivity

     activity;        private  Button  convertButton;        private  EditText  amountField;        @Before        public  void  setUp()  {                activity  =  Robolectric.buildActivity(MainActivity.class).create().get();                convertButton  =  (Button)  activity.findViewById(R.id.convert_cash_button);                amountField  =  (EditText)  activity.findViewById(R.id.currency_input_field);        }        @Test        public  void  whenTheActivityIsLoadedTheEurRadioButtonShouldBeChecked()  {                RadioButton  radioButton  =  (RadioButton)  activity.findViewById(R.id.eurs_radio_button);                assertThat(radioButton.isChecked(),  equalTo(true));        } } View VALIDATION sábado, 30 de noviembre de 13
  8. @Test        public  void  whenTheConvertButtonIsPressedTheDetailActivityIsCalled()  {    

               Button  convertButton  =  (Button)  activity.findViewById(R.id.convert_cash_button);                convertButton.performClick();                ShadowActivity  shadowActivity  =  shadowOf(activity);                Intent  startedIntent  =  shadowActivity.getNextStartedActivity();                ShadowIntent  shadowIntent  =  shadowOf(startedIntent); assertThat(shadowIntent.getComponent().getClassName(),   equalTo(DetailActivity.class.getName()));        } @Test        public  void  whenTheConvertButtonIsClickedTheAmountIsSentToTheNextActivity()  {                amountField.setText("10");                convertButton.performClick();                ShadowActivity  shadowActivity  =  shadowOf(activity);                Intent  startedIntent  =  shadowActivity.getNextStartedActivity();                ShadowIntent  shadowIntent  =  shadowOf(startedIntent);                assertThat((String)  shadowIntent.getExtras().get("amount"),  equalTo("10"));        } View Behavior sábado, 30 de noviembre de 13
  9. ActivityInstrumentationTestCase2 ‣Most basic integration test ‣Implements instrumentation to control ‣RunOnUIThread

    ‣Small, Medium and Large tests ‣Specific tests for Provider and Services sábado, 30 de noviembre de 13
  10. TYPE OF TESTS Running all small tests: adb shell am

    instrument -w - e size small com.android.foo/ android.test.InstrumentationTestRunner Running all medium tests: adb shell am instrument - w -e size medium com.android.foo/ android.test.InstrumentationTestRunner Running all large tests: adb shell am instrument -w - e size large com.android.foo/ android.test.InstrumentationTestRunner Source: http://googletesting.blogspot.com.es/2010/12/test-sizes.html sábado, 30 de noviembre de 13
  11. @Override protected  void  setUp()  throws  Exception  {      

     super.setUp();        setActivityInitialTouchMode(false);        activity  =  (MainActivity)  getActivity(); } public  void  testThatSettedAnAmountGoToDetailActivityAndShowsThatAmountConverted()  {        ActivityMonitor  monitor  =  getInstrumentation().addMonitor(DetailActivity.class.getName(),null,  false);        final  EditText  amountField  =  (EditText)  activity.findViewById(R.id.currency_input_field);        final  Button  convertButton  =  (Button)  activity.findViewById(R.id.convert_cash_button);        activity.runOnUiThread(new  Runnable()  {                @Override                public  void  run()  {                        amountField.setText("10");                        convertButton.performClick();                }        });        DetailActivity  startedActivity  =  (DetailActivity)  monitor.waitForActivityWithTimeout(5000);        assertNotNull(startedActivity);        TextView  convertAmountText  =  (TextView)  startedActivity.findViewById(R.id.amount_converted);        assertEquals("7.4",  convertAmountText.getText()); } EXAMPLE sábado, 30 de noviembre de 13
  12. ESPRESSO ‣No waits, sleeps, syncs... ‣Used by over 30 apps

    within Google ‣But for early adopters sábado, 30 de noviembre de 13
  13. public  void  testThatSettedAnAmountGoToDetailActivityAndShowsThatAmountConverted()   {          

         onView(withId(R.id.currency_input_field)).perform(typeText("10"));                onView(withId(R.id.convert_cash_button)).perform(click());                onView(withId(R.id.amount_converted)).check(matches(withText("7.4")));                assertTrue(true);        } EXAMPLES onData(allOf(is(instanceOf(String.class)), is("Americano"))) .perform(click()); sábado, 30 de noviembre de 13