SlideShare a Scribd company logo
droidcon 2009
  testing on android
                                                   london, december 2009

                                              diego torres milano
                                                 diego@codtech.com
copyright © 2009  cod technologies ltd  www.codtech.com
“Never test the depth of 
the water with both feet.”
                                                           ­­ Anonymous




      copyright © 2009  cod technologies ltd  www.codtech.com
agenda
●   test driven development
●   behavior driven development
●   building blocks
●   your first tdd android application
●   writing tests


             copyright © 2009  cod technologies ltd  www.codtech.com
resources


●   http://android.codtech.com/droidcon2009




             copyright © 2009  cod technologies ltd  www.codtech.com
after this section you will
after this section you will...




                                                 ●   understand test driven 
                                                     development
                                                 ●   be introduced to behavior 
                                                     driven development
                                                 ●   recognize test building 
                                                     blocks



                                 copyright © 2009  cod technologies ltd  www.codtech.com
what is test driven development ?


      TDD is the strategy of 
     starting the development 
  process by the test cases and 
  then provide the software that 
        satisfies these tests


         copyright © 2009  cod technologies ltd  www.codtech.com
test driven development




                                                            uml activity diagram




         copyright © 2009  cod technologies ltd  www.codtech.com
kinds of automated tests
●   unit tests
      –   written by programmers
      –   for programmers
      –   in a programming language
●   functional or acceptance tests
      –   written by business people and QA
      –   for business people
      –   in a high level language
                                                            check FitNesse www.fitnesse.org


                 copyright © 2009  cod technologies ltd  www.codtech.com
behavior driven development
●   evolution in the thinking behind TDD
●   common vocabulary between business and 
    technology
●   framework of activity based on three principles
      –   business and technology should refer to the same 
          system in the same way
      –   any system should have an identified, verifiable 
          value to the business
      –   up­front analysis, design and planning all have a 
          diminishing return               http://behaviour­driven.org
                                                                             http://jbehave.org
                   copyright © 2009  cod technologies ltd  www.codtech.com
scenario
●   text scenario

     Given I am not logged in
     When I log in as Liz with a password JBehaver
     Then I should see a message, "Welcome, Liz!"

●   defining steps
       @Given("I am not logged in")
       public void logOut() {
           currentPage.click("logout");
       }




               copyright © 2009  cod technologies ltd  www.codtech.com
testing on android
●   android platform integrates a 
    testing framework
●   it's based on Junit 3
●   supports
    –   unit tests
    –   functional tests
    –   activity tests
    –   mock objects
    –   utilities to simplify test                    Portions of this page are reproduced from work created and shared by 
                                                              Google and used according to terms described in the Creative 
        creation                                                                          Commons 2.5 Attribution License.



                     copyright © 2009  cod technologies ltd  www.codtech.com
is this all the documentation ?




                                                   a framework for writing 
                                                   android test cases and 
                                                         suites. (?)




         copyright © 2009  cod technologies ltd  www.codtech.com
ActivityInstrumentationTestCase2
●   functional testing of single Activity
●   Activity  created used system infrastructure
●   Activity can be manipulated
●   Tests can be annotated with @UiThreadTest
●   Intents can be injected with 
    setActivityIntent()
●   sendKeys() can be used to simulate user 
    interaction


               copyright © 2009  cod technologies ltd  www.codtech.com
uml class diagram




        copyright © 2009  cod technologies ltd  www.codtech.com
ApplicationTestCase
●   test Application in controlled environment
●   basic lyfecycle support
      –   onCreate() called after createApplication()
      –   tearDown() calls onDestroy()
●   mock Context can be injected
●   Application can be terminated with 
    terminateApplication()




                 copyright © 2009  cod technologies ltd  www.codtech.com
ActivityUnitTestCase
●   isolated testing of a single Activity
●   Activity created with minimal connection to the 
    system
●   mocked dependencies can be injected
●   Activity will not participate in the normal 
    interactions with the system
●   some methods should be avoided and will throw 
    exceptions if called


               copyright © 2009  cod technologies ltd  www.codtech.com
ProviderTestCase2<T>
●   isolated testing of a ContentProvider
●   uses a MockContentResolver to
      –   access the provider
      –   restricts access to filesystem (db & files)
      –   injects IsolatedContext
●   environment managed by setUp() and 
    tearDown()




                  copyright © 2009  cod technologies ltd  www.codtech.com
ServiceTestCase<T>
●   framework to test Services
●   basic support for lifecycle
      –   onCreate() called after startService(Intent) or 
          bindService(Intent)
      –   depending on how was started tearDown() calls 
          appropriate method
●   mock objects can be injected by
      –   setApplication()
      –   setContext()


                  copyright © 2009  cod technologies ltd  www.codtech.com
AndroidTestCase
●   base class that can be extended to support 
    different requirements
●   use this if you need
      –   isolate components
      –   test custom Views
      –   test permissions
      –   access Resources




                 copyright © 2009  cod technologies ltd  www.codtech.com
ViewAsserts
●   useful assertions about Views
      –   Views are aligned in several ways
      –   ViewGroups contain Views
      –   View is on screen
      –   View has specific screen coordinates




                 copyright © 2009  cod technologies ltd  www.codtech.com
TouchUtils
●   use these methods to generate touch events
●   clickView() to simulate touching
●   drag...() to touch and drag
●   longClick() for touching and holding
●   scroll...() to simulate different scrolling
●   tapView() to touch and release quickly




                copyright © 2009  cod technologies ltd  www.codtech.com
android.test.mock
all classes has non­functional methods
●   MockApplication
●   MockContentResolver
●   MockContext
●   MockDialogInterface
●   MockPackageManager
●   MockResources



             copyright © 2009  cod technologies ltd  www.codtech.com
“You know you've achieved 
perfection in design, not when 
you have nothing more to add, 
but when you have nothing 
more to take away.”

                                     ­­ Antoine de Saint­Exupery




      copyright © 2009  cod technologies ltd  www.codtech.com
after this section you will
after this section you will...




                                                 ●   be able to create a project 
                                                     and its corresponding tests 
                                                     project
                                                 ●   apply test driven 
                                                     development techniques
                                                 ●   get acquainted with android 
                                                     tests


                                 copyright © 2009  cod technologies ltd  www.codtech.com
design
    converts
    temperatures
    from celsius e
                  r
              us to
            e
       n th
   whehrenheit a d
                an
                                                                           if
                                                                               the
    fa
            rsa                                                           err     re'
       e- e
         t
    vicen vers       one                                                      or      s a
                                                                                          nd
         atur  e in                                                     dis
                                                                            pla
                                                                                 sh o
                                                                                     uld
 temper         ther
                        is                                             (O
                                                                         )
                                                                               ye
                                                                                 d        be
            e o                                                                     he
      ld th
                                                                                       re
  fie           ed
         updat
                    lly
            m  atica
       auto




                                                        we l
                                                             eave
                                                        f or       s p ac
                                                              keyb        e
                                                                  o ar d




                      copyright © 2009  cod technologies ltd  www.codtech.com
create project




                                                             Choose the 
                                                             build target




         copyright © 2009  cod technologies ltd  www.codtech.com
create test project
 always create a 
   test project




                                                                              other values are 
                                                                               automatically 
                                                                                  selected




                    copyright © 2009  cod technologies ltd  www.codtech.com
create test case




                                                                           to create the test for 
                                                                            the Activity we use 
                                                                           ActivityInstrument
                                                                           ationTestCase2<T>



create method 
    stubs


                                                                           the Activity as the 
                                                                            class under test




                 copyright © 2009  cod technologies ltd  www.codtech.com
check generated test case
  /**
   * Copyright © 2009 COD Technologies Ltd. All rights reserved.
   */
  package com.codtech.android.training.tctdd1.test;

  import android.test.ActivityInstrumentationTestCase2;

  import
   adjust stub 
  com.codtech.android.training.tctdd1.TemperatureConverterActivity;
constructor to pass 
required arguments 
   public class
      to super
                   TemperatureConverterActivityTests extends
             ActivityInstrumentationTestCase2<TemperatureConverterActivity> {

        /**
         * @param name
         */
        public TemperatureConverterActivityTests(String name) {
            super("com.codtech.android.training.tctdd1",
                TemperatureConverterActivity.class);
            setName(name);
        }

        // setUp() and tearDown() not showed
  }

                       copyright © 2009  cod technologies ltd  www.codtech.com
setUp

/* (non-Javadoc)
 * @see android.test.ActivityInstrumentationTestCase2#setUp()
 */
                                                              these constants are 
protected void setUp() throws Exception {                      not yet created, we 
    super.setUp();                                              need to add the 
                                                                                  Views and Ids to the 
    final TemperatureConverterActivity activity =                     getActivity(); layout

    celsius = (EditText)activity.findViewById(
        com.codtech.android.training.tctdd1.R.id.celsius);

    fahrenheit = (EditText)activity.findViewById(
        com.codtech.android.training.tctdd1.R.id.fahrenheit);

}

     create fields 
    when necessary




                      copyright © 2009  cod technologies ltd  www.codtech.com
layout


                                                                     Ids should 
                                                                       satisfy 
                                                                      previous 
                                                                   requirements




         copyright © 2009  cod technologies ltd  www.codtech.com
add some UI tests
@SmallTest
public void testSimpleCreate() {
    assertNotNull(getActivity());

    assertNotNull(celsius);
    assertNotNull(fahrenheit);

    ViewAsserts.assertOnScreen(fahrenheit.getRootView(), celsius);
    ViewAsserts.assertOnScreen(celsius.getRootView(), fahrenheit);
}

@SmallTest
public void testAlignment() {
    ViewAsserts.assertRightAligned(celsius, fahrenheit);
    ViewAsserts.assertLeftAligned(celsius, fahrenheit);
}

@SmallTest
public void testFiledsStartEmpty() {
    assertTrue("Celsius field starts not empty",
        "".equals(celsius.getText().toString()));
    assertTrue("Fahrenheit field starts not empty",
        "".equals(fahrenheit.getText().toString()));
}

                  copyright © 2009  cod technologies ltd  www.codtech.com
now some functional tests
    we run the test in the 
         UI thread



@UiThreadTest
public void testFahrenheitToCelsiusConversion() {                                                    we don't have a 
    celsius.clear();                                                                               class implementing 
    fahrenheit.clear();                                                                                setNumber(), 
                                                                                                    getNumber() and 
    final double f = 32.5;                                                                         clear() so we will be 
                                                                                                      creating it soon
    fahrenheit.requestFocus();
    fahrenheit.setNumber(f);
    celsius.requestFocus();
    final double c = TemperatureConverter.fahrenheitToCelsius(f);
    final double cr = celsius.getNumber();
    final double delta = Math.abs(c - cr);
    final String msg = "" + f + "F should be " + c + "C but was " +
        cr + " (delta " + delta + ")";
    assertTrue(msg, delta < 0.005);
}
                                                                              we don't have a 
                                                                           TemperatureConverter 
                                                                                  either



                              copyright © 2009  cod technologies ltd  www.codtech.com
and more tests
   don't run this test 
     in UI thread


@SmallTest
public void testCelsiusToFahrenheitConversion() {
    final double c = -105.35;
    TouchUtils.tapView(this, celsius);
                                                            create method stub in 
    sendKeys("MINUS 1 0 5 PERIOD 3 5");
                                                            TemperatureConverter
    final double cr = celsius.getNumber();
    assertEquals("Send keys should have set " + c + " but set " +
        cr, c, cr);
    final double f = TemperatureConverter.celsiusToFahrenheit(c);
    final double fr = fahrenheit.getNumber();
    final double delta = Math.abs(f - fr);
    final String msg = "" + c + "C should be " + f + "F but was " +
        fr + " (delta " + delta + ")";
    assertTrue(msg, delta < 0.005);
}




                          copyright © 2009  cod technologies ltd  www.codtech.com
create EditNumber class
                                                                       create a 
                                                                         new 
                                                                      package for 
                                                                        views




                                                                        extend 
                                                                        EditText




                                                                  once we create 
                                                                  EditNumber we 
                                                                  should refactor 
                                                                  our main layout 
                                                                    and fields




        copyright © 2009  cod technologies ltd  www.codtech.com
create TemperatureConverter class




         copyright © 2009  cod technologies ltd  www.codtech.com
create a TestCase




   create 
   stubs
                                                                          test 
                                                                  TemperatureConverter




             copyright © 2009  cod technologies ltd  www.codtech.com
select methods to test




         copyright © 2009  cod technologies ltd  www.codtech.com
complete actual tests
public void testFahrenheitToCelsius() {
    for (double c: conversionTableDouble.keySet()) {
        final double f = conversionTableDouble.get(c);
        final double cr = TemperatureConverter.fahrenheitToCelsius(f);
        final double delta = Math.abs(c - cr);
        final String msg = "" + f + "F should be " + c + "C but is " +
            cr + " (delta " + delta + ")";
        assertTrue(msg, delta < 0.0001);
    }
}


public void testCelsiusToFahrenheit() {
    for (double c: conversionTableDouble.keySet()) {
        final double f = conversionTableDouble.get(c);
        final double fr = TemperatureConverter.celsiusToFahrenheit(c);
        final double delta = Math.abs(f - fr);
        final String msg = "" + c + "C should be " + f + "F but is " +
            fr + " (delta " + delta + ")" ;
        assertTrue(msg, delta < 0.0001);
    }
}



                  copyright © 2009  cod technologies ltd  www.codtech.com
test exceptions
public void testAbsoluteZeroCelsius() {
    Exception e = null;

    try {
        TemperatureConverter.celsiusToFahrenheit(-274);
    }
        catch (RuntimeException re) {
    }

    assertNotNull("Absolute zero C not detected", e);
}

public void testAbsoluteZeroFahrenheit() {
    Exception e = null;

    try {
        TemperatureConverter.fahrenheitToCelsius(-460);
    }
    catch (RuntimeException re) {
        e = re;
    }

    assertNotNull("Absolute zero F not detected", e);
}

                  copyright © 2009  cod technologies ltd  www.codtech.com
conversion table
●   simple conversion table to run several tests
private static final HashMap<Double, Double> conversionTableDouble =
    new HashMap<Double, Double>();

static {
    // initialize (c, f) pairs
    conversionTableDouble.put(0.0, 32.0);
    conversionTableDouble.put(100.0, 212.0);
    conversionTableDouble.put(-1.0, 30.20);
    conversionTableDouble.put(-100.0, -148.0);
    conversionTableDouble.put(32.0, 89.60);
    conversionTableDouble.put(-40.0, -40.0);
    conversionTableDouble.put(-273.0, -459.40);
}




                  copyright © 2009  cod technologies ltd  www.codtech.com
run tests




                                                                      conversion tests fail 
                                                                      because we haven't 
                                                                       implemented it yet




            copyright © 2009  cod technologies ltd  www.codtech.com
TemperatureConverter
package com.codtech.android.training.tctdd1;

public class TemperatureConverter {

    public static final double ABSOLUTE_ZERO_C = -273.0d;
    public static final double ABSOLUTE_ZERO_F = -459.4d;

    private static final String ERROR_MESSAGE_BELOW_ZERO_FMT =
        "Invalid temperature: %.2f%c below absolute zero";

    public static double celsiusToFahrenheit(double c) {
        if (c < ABSOLUTE_ZERO_C) {
             throw new RuntimeException(
                 String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, c, 'C'));
        }
        return (c * 1.8d + 32);
    }

    public static double fahrenheitToCelsius(double f) {
        if (f < ABSOLUTE_ZERO_F) {
            throw new RuntimeException(
                 String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, f, 'F'));
        }
        return ((f - 32) / 1.8d);
    }
}


                    copyright © 2009  cod technologies ltd  www.codtech.com
run tests




                                                                             tests fail now because we 
                                                                              are doing the conversion 
                                                                              right but we are invoking 
     conversion tests                                                             empty methods in 
        succeded                                                                EditNumber that don't 
                                                                                     update the ui




                   copyright © 2009  cod technologies ltd  www.codtech.com
implement EditNumber methods
package com.codtech.android.training.tctdd1.view;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.EditText;

public class EditNumber extends EditText {

    public EditNumber(Context context) {
        super(context);
    }

    public EditNumber(Context context, AttributeSet attrs) {
        super(context, attrs);
    }                                                                         convenience methods 
                                                                              delegating to EditText
    public void clear() {
        setText("");
    }

    public void setNumber(double f) {
        setText(Double.toString(f));
    }

    public double getNumber() {
        return Double.valueOf(getText().toString());
    }
}

                    copyright © 2009  cod technologies ltd  www.codtech.com
run tests




                                                                       a NumberFormatException 
                                                                      because we are not changing 
                                                                        the other field when some 
                                                                       new temperature is entered 
                                                                       and thus the field is empty




            copyright © 2009  cod technologies ltd  www.codtech.com
onCreate
  /** Called when the activity is first created. */
  @SuppressWarnings("unchecked")
  @Override
  public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
                                                                            add change listener 
      celsius = (EditNumber)findViewById(R.id.celsius);       to these fields
      fahrenheit = (EditNumber)findViewById(R.id.fahrenheit);

      try {
          Class[] args = new Class[] { double.class };
          celsius.addTextChangedListener(
              new TemperatureChangedWatcher(fahrenheit,
                  TemperatureConverter.class.getMethod(
                      "celsiusToFahrenheit", args)));
          fahrenheit.addTextChangedListener(
              new TemperatureChangedWatcher(celsius,
                  TemperatureConverter.class.getMethod(
                      "fahrenheitToCelsius", args)));
      } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
  }

                  copyright © 2009  cod technologies ltd  www.codtech.com
TemperatureChangedWatcher
private static class TemperatureChangedWatcher implements TextWatcher {
    private EditNumber dest;
    private Method convert;

   public TemperatureChangedWatcher(EditNumber dest, Method convert) {
       this.dest = dest; this.convert = convert;
   }

   @Override
   public void afterTextChanged(Editable s) {
   }

   @Override
   public void beforeTextChanged(CharSequence s, int start, int count,
           int after) {
   }

   @Override
   public void onTextChanged(CharSequence s, int start, int before,
           int count) {

       if (!dest.hasWindowFocus() || dest.hasFocus() || s == null ) {
           return;
       }
   // continued ...

                      copyright © 2009  cod technologies ltd  www.codtech.com
TemperatureChangedWatcher
        final String ss = s.toString();
        if ( "".equals(ss) ) {
            dest.clear();
            return;
        }

        try {
            final double result = (Double)
                convert.invoke(TemperatureConverter.class,
                    Double.parseDouble(ss));
            // display only 2 decimals
            dest.setNumber(Math.rint(result*100)/100);
        } catch (NumberFormatException e) {
            // WARNING
            // this is generated while a number is entered,
            // for example just a -' so we don't want to show the error
        } catch (Exception e) {
            dest.setError(e.getCause().getLocalizedMessage());
        }
    }
}



                  copyright © 2009  cod technologies ltd  www.codtech.com
tests succeed




        copyright © 2009  cod technologies ltd  www.codtech.com
temperature converter
    converts
    temperatures
    from celsius e
                  r
              us to
            e
       n th
   whehrenheit a d
                an
                                                                           if
                                                                               the
    fa
            rsa                                                           err     re'
       e- e
         t
    vicen vers       one                                                      or      s a
                                                                                          nd
         atur  e in                                                     dis
                                                                            pla
                                                                                 sh o
                                                                                     uld
 temper         ther
                        is                                             (O
                                                                         )
                                                                               ye
                                                                                 d        be
            e o                                                                     he
      ld th
                                                                                       re
  fie           ed
         updat
                    lly
            m  atica
       auto




                                                        we l
                                                             eave
                                                        f or       s p ac
                                                              keyb        e
                                                                  o ar d




                      copyright © 2009  cod technologies ltd  www.codtech.com
instrumentation
●   Dev Tools → Instrumentation → TCTDD1 Tests




             copyright © 2009  cod technologies ltd  www.codtech.com
eclipse
●   TCTDD1Test → Run As → Android JUnit Test




             copyright © 2009  cod technologies ltd  www.codtech.com
command line

 diego@bruce:~$ adb -e shell am instrument -w -e class
 com.codtech.android.training.tctdd1.test.TemperatureCo
 nverterActivityTests
 com.codtech.android.training.tctdd1.test/android.test.
 InstrumentationTestRunner

 com.codtech.android.training.tctdd1.test.TemperatureCo
 nverterActivityTests:.....
 Test results for InstrumentationTestRunner=.....
 Time: 5.564

 OK (5 tests)




                copyright © 2009  cod technologies ltd  www.codtech.com
EditNumberTests



                                                                  AndroidTestCase




        copyright © 2009  cod technologies ltd  www.codtech.com
select methods to test




         copyright © 2009  cod technologies ltd  www.codtech.com
constructor and setUp

/**
 * @param name
 */
public EditNumberTests(String name) {
    super();
    setName(name);
}
                                                                            creating a mock 
                                                                                context
/* (non-Javadoc)
 * @see android.test.AndroidTestCase#setUp()
 */
protected void setUp() throws Exception {
    super.setUp();
    mockContext = new IsolatedContext(new MockContentResolver(),
        getContext());
    editNumber = new EditNumber(mockContext);
    editNumber.setFocusable(true);
}




                  copyright © 2009  cod technologies ltd  www.codtech.com
complete actual tests
/**
 * Test method for EditNumber#EditNumber(android.content.Context)
 */
public void testEditNumberContext() {
    assertNotNull(new EditNumber(mockContext));
}

/**
 * Test method for EditNumber#EditNumber(Context, AttributeSet)
 */
public void testEditNumberContextAttributeSet() {
    // TODO
    // use a real AttributeSet for this test not null
    assertNotNull(new EditNumber(mockContext, null));
}

/**
 * Test method for EditNumber#clear()
 */
public void testClear() {
    editNumber.setText("1234");
    editNumber.clear();
    assertEquals("editNumber should have been cleared",
        "", editNumber.getText().toString());
}

                    copyright © 2009  cod technologies ltd  www.codtech.com
complete actual tests

public void testSetNumber() {
    final double d = 1.23d;
    editNumber.setNumber(d);
    final double dr = editNumber.getNumber();
    final String msg = "editNumber should be " + d + " but is " + dr;
    assertEquals(msg, d, dr);
}



public void testGetNumber() {
    final double d = 0.98d;
    final String ds = Double.toString(d);
    editNumber.setText(ds);
    final double dr = editNumber.getNumber();
    final String msg = "editNumber should be " + ds + " but is " + dr;
    assertEquals(msg, d, dr);
}




                  copyright © 2009  cod technologies ltd  www.codtech.com
input test
public class TemperatureConverterActivityTests extends
       ActivityInstrumentationTestCase2<TemperatureConverterActivity> {

    // …

    @SmallTest
    public void testInputFilter() {
        TouchUtils.tapView(this, celsius);
        final Double n = -1.234d;
        sendKeys("MINUS 1 PERIOD 2 PERIOD 3 PERIOD 4");
        Object nr = null;
        try {
            nr = celsius.getNumber();
        }
        catch (NumberFormatException e) {
            nr = celsius.getText();
        }

        final String msg = "-1.2.3.4 should be filtered to " + n +
            " but is " + nr;
        assertEquals(msg, n, nr);
    }
}


                  copyright © 2009  cod technologies ltd  www.codtech.com
input filter

public class EditNumber extends EditText {

    //   …
                                                                             invoke init() from 
                                                                               constructors
    /**
     * Initialization.
     * Set filter.
     *
     */
    private void init() {
        // DigistKeyListener.getInstance(true, true) returns an
        // instance that accepts digits, sign and decimal point
        final InputFilter[] filters = new InputFilter[]
            { DigitsKeyListener.getInstance(true, true) };

         setFilters(filters);
    }

}




                   copyright © 2009  cod technologies ltd  www.codtech.com
resources
●   http://dtmilano.blogspot.com
●   http://easymock.org
●   http://code.google.com/p/hamcrest (matchers)
●   http://mockito.org/
●   http://developer.android.com/guide/developing/t
    ools/monkey.html (ui exerciser)
●   http://ricston.com/ricston­training­for­android/
●   http://android.codtech.com

               copyright © 2009  cod technologies ltd  www.codtech.com
“If things seem under control, 
 you're not going fast enough.”
                                                         ­­ Mario Andretti




     copyright © 2009  cod technologies ltd  www.codtech.com
thank you
  testing on android
                                                   london, december 2009

                                    diego torres milano
                                               diego@codtech.com

copyright © 2009  cod technologies ltd  www.codtech.com

More Related Content

What's hot (20)

PDF
Android testing part i
Kan-Han (John) Lu
 
PDF
Inside Android Testing
Fernando Cejas
 
PDF
Robotium - sampath
Sampath Muddineni
 
PPTX
Android Native Apps Development
Intel Software Brasil
 
PDF
Dagger for android
Kan-Han (John) Lu
 
PDF
Discovering Flaws in Security-Focused Static Analysis Tools for Android using...
Kevin Moran
 
PDF
Android Testing: An Overview
SmartLogic
 
PPTX
Appium Mobile Testing: Nakov at BurgasConf - July 2021
Svetlin Nakov
 
DOCX
Y1 gd engine_terminology amy brockbank
amybrockbank
 
DOCX
Lewis brady engine_terminology (edited version)
LewisB2013
 
PPT
SynapseIndia mobile apps deployment framework architecture
Synapseindiappsdevelopment
 
DOCX
iain goodyear game engines definitions woprks 2 cristian galliano
crisgalliano
 
DOCX
Y1 gd engine_terminology (2)
crisgalliano
 
PPT
Ensuring code quality
MikhailVladimirov
 
PDF
MOET: Mobile End-to-End Testing
mobiletestsummit
 
PDF
Code and Conquer with Globe Labs, October 27, 2012
jobandesther
 
PDF
Android tutorial
Alberto Jr Gaudicos
 
ODP
xUnit and TDD: Why and How in Enterprise Software, August 2012
Justin Gordon
 
PDF
Introduction to Android Window System
National Cheng Kung University
 
PDF
Android Test Automation Workshop
Eduardo Carrara de Araujo
 
Android testing part i
Kan-Han (John) Lu
 
Inside Android Testing
Fernando Cejas
 
Robotium - sampath
Sampath Muddineni
 
Android Native Apps Development
Intel Software Brasil
 
Dagger for android
Kan-Han (John) Lu
 
Discovering Flaws in Security-Focused Static Analysis Tools for Android using...
Kevin Moran
 
Android Testing: An Overview
SmartLogic
 
Appium Mobile Testing: Nakov at BurgasConf - July 2021
Svetlin Nakov
 
Y1 gd engine_terminology amy brockbank
amybrockbank
 
Lewis brady engine_terminology (edited version)
LewisB2013
 
SynapseIndia mobile apps deployment framework architecture
Synapseindiappsdevelopment
 
iain goodyear game engines definitions woprks 2 cristian galliano
crisgalliano
 
Y1 gd engine_terminology (2)
crisgalliano
 
Ensuring code quality
MikhailVladimirov
 
MOET: Mobile End-to-End Testing
mobiletestsummit
 
Code and Conquer with Globe Labs, October 27, 2012
jobandesther
 
Android tutorial
Alberto Jr Gaudicos
 
xUnit and TDD: Why and How in Enterprise Software, August 2012
Justin Gordon
 
Introduction to Android Window System
National Cheng Kung University
 
Android Test Automation Workshop
Eduardo Carrara de Araujo
 

Viewers also liked (20)

PDF
Android Building, Testing and reversing
Enrique López Mañas
 
PDF
Unit testing and Android
Tomáš Kypta
 
PPTX
Android Automation Testing with Selendroid
Vikas Thange
 
PDF
How to setup unit testing in Android Studio
tobiaspreuss
 
PDF
Performance testing of mobile apps
vodQA
 
PPTX
Mobile testing: Android, iOS, BlackBerry
QA Club Kiev
 
PPTX
Txt Introduction
Logic Solutions, Inc.
 
PPT
Data Storage In Android
Aakash Ugale
 
PDF
QA Fest 2016. Денис Яременко. Как облегчить процесс мобильного тестирования
QAFest
 
PDF
Introduction to Trusted Computing
Maksim Djackov
 
PDF
Android UI Testing with uiautomator
Jana Moudrá
 
PDF
Android complete basic Guide
AKASH SINGH
 
PDF
Android Data Persistence
Jussi Pohjolainen
 
PPTX
Android Training (Storing & Shared Preferences)
Khaled Anaqwa
 
PPTX
Android Training (Content Provider)
Khaled Anaqwa
 
PPT
Day 4: Android: UI Widgets
Ahsanul Karim
 
PPTX
Testing for Android: When, Where, and How to Successfully Use Test Automation
Trent Peterson
 
PDF
Introduction to android testing - oscon 2012
OSCON Byrum
 
PPTX
Unit Testing Android Applications
Rody Middelkoop
 
PPTX
Android Performance Tips & Tricks
Sergii Zhuk
 
Android Building, Testing and reversing
Enrique López Mañas
 
Unit testing and Android
Tomáš Kypta
 
Android Automation Testing with Selendroid
Vikas Thange
 
How to setup unit testing in Android Studio
tobiaspreuss
 
Performance testing of mobile apps
vodQA
 
Mobile testing: Android, iOS, BlackBerry
QA Club Kiev
 
Txt Introduction
Logic Solutions, Inc.
 
Data Storage In Android
Aakash Ugale
 
QA Fest 2016. Денис Яременко. Как облегчить процесс мобильного тестирования
QAFest
 
Introduction to Trusted Computing
Maksim Djackov
 
Android UI Testing with uiautomator
Jana Moudrá
 
Android complete basic Guide
AKASH SINGH
 
Android Data Persistence
Jussi Pohjolainen
 
Android Training (Storing & Shared Preferences)
Khaled Anaqwa
 
Android Training (Content Provider)
Khaled Anaqwa
 
Day 4: Android: UI Widgets
Ahsanul Karim
 
Testing for Android: When, Where, and How to Successfully Use Test Automation
Trent Peterson
 
Introduction to android testing - oscon 2012
OSCON Byrum
 
Unit Testing Android Applications
Rody Middelkoop
 
Android Performance Tips & Tricks
Sergii Zhuk
 
Ad

Similar to Testing on Android (20)

PDF
Programmer testing
Joao Pereira
 
PDF
The Future Tester at Suncorp - A Journey of Building Quality In Through Agile
Craig Smith
 
KEY
Introduction to Acceptance Test Driven Development
Steven Mak
 
PDF
Managing Software Debt - Quality Debt Focus - QASIG Kirkland
Chris Sterling
 
PDF
Android Development Workshop V2
Diego Torres Milano
 
PDF
ATDD for Web Apps
ekantola
 
PDF
Agile Testing
Lanvige Jiang
 
PDF
Test Driven Sysadmin
johanku
 
PDF
Software Testing on the Web
Martin Schütte
 
PDF
Webapp acceptance testing a case study
ekantola
 
PDF
Atdd In Practice (Agile Tour 2010 Qingdao)
Yi Xu
 
PDF
Testing In Agile
Ari Tanninen
 
PDF
How To Fit Testing Into The Iteration
Rally Software
 
PPTX
Software testing
Nico Heidtke
 
PDF
Android Development Tutorial V3
Diego Torres Milano
 
PDF
NDC 2011 - SpecFlow: Pragmatic BDD for .NET
jbandi
 
PDF
What CS Class Didn't Teach About Testing
Camille Bell
 
PDF
ATDD BY Example With Cucumber
Doug Morgan
 
PDF
Test Driven Development
CodeAndroid
 
KEY
ATDD in Practice
Steven Mak
 
Programmer testing
Joao Pereira
 
The Future Tester at Suncorp - A Journey of Building Quality In Through Agile
Craig Smith
 
Introduction to Acceptance Test Driven Development
Steven Mak
 
Managing Software Debt - Quality Debt Focus - QASIG Kirkland
Chris Sterling
 
Android Development Workshop V2
Diego Torres Milano
 
ATDD for Web Apps
ekantola
 
Agile Testing
Lanvige Jiang
 
Test Driven Sysadmin
johanku
 
Software Testing on the Web
Martin Schütte
 
Webapp acceptance testing a case study
ekantola
 
Atdd In Practice (Agile Tour 2010 Qingdao)
Yi Xu
 
Testing In Agile
Ari Tanninen
 
How To Fit Testing Into The Iteration
Rally Software
 
Software testing
Nico Heidtke
 
Android Development Tutorial V3
Diego Torres Milano
 
NDC 2011 - SpecFlow: Pragmatic BDD for .NET
jbandi
 
What CS Class Didn't Teach About Testing
Camille Bell
 
ATDD BY Example With Cucumber
Doug Morgan
 
Test Driven Development
CodeAndroid
 
ATDD in Practice
Steven Mak
 
Ad

Recently uploaded (20)

PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PPTX
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
PDF
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PDF
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Biography of Daniel Podor.pdf
Daniel Podor
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Q2 FY26 Tableau User Group Leader Quarterly Call
lward7
 
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
From Code to Challenge: Crafting Skill-Based Games That Engage and Reward
aiyshauae
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 

Testing on Android

  • 1. droidcon 2009 testing on android london, december 2009 diego torres milano [email protected] copyright © 2009  cod technologies ltd  www.codtech.com
  • 2. “Never test the depth of  the water with both feet.” ­­ Anonymous copyright © 2009  cod technologies ltd  www.codtech.com
  • 3. agenda ● test driven development ● behavior driven development ● building blocks ● your first tdd android application ● writing tests copyright © 2009  cod technologies ltd  www.codtech.com
  • 4. resources ● http://android.codtech.com/droidcon2009 copyright © 2009  cod technologies ltd  www.codtech.com
  • 5. after this section you will after this section you will... ● understand test driven  development ● be introduced to behavior  driven development ● recognize test building  blocks copyright © 2009  cod technologies ltd  www.codtech.com
  • 6. what is test driven development ? TDD is the strategy of  starting the development  process by the test cases and  then provide the software that  satisfies these tests copyright © 2009  cod technologies ltd  www.codtech.com
  • 7. test driven development uml activity diagram copyright © 2009  cod technologies ltd  www.codtech.com
  • 8. kinds of automated tests ● unit tests – written by programmers – for programmers – in a programming language ● functional or acceptance tests – written by business people and QA – for business people – in a high level language check FitNesse www.fitnesse.org copyright © 2009  cod technologies ltd  www.codtech.com
  • 9. behavior driven development ● evolution in the thinking behind TDD ● common vocabulary between business and  technology ● framework of activity based on three principles – business and technology should refer to the same  system in the same way – any system should have an identified, verifiable  value to the business – up­front analysis, design and planning all have a  diminishing return http://behaviour­driven.org http://jbehave.org copyright © 2009  cod technologies ltd  www.codtech.com
  • 10. scenario ● text scenario Given I am not logged in When I log in as Liz with a password JBehaver Then I should see a message, "Welcome, Liz!" ● defining steps @Given("I am not logged in") public void logOut() { currentPage.click("logout"); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 11. testing on android ● android platform integrates a  testing framework ● it's based on Junit 3 ● supports – unit tests – functional tests – activity tests – mock objects – utilities to simplify test Portions of this page are reproduced from work created and shared by  Google and used according to terms described in the Creative  creation Commons 2.5 Attribution License. copyright © 2009  cod technologies ltd  www.codtech.com
  • 12. is this all the documentation ? a framework for writing  android test cases and  suites. (?) copyright © 2009  cod technologies ltd  www.codtech.com
  • 13. ActivityInstrumentationTestCase2 ● functional testing of single Activity ● Activity  created used system infrastructure ● Activity can be manipulated ● Tests can be annotated with @UiThreadTest ● Intents can be injected with  setActivityIntent() ● sendKeys() can be used to simulate user  interaction copyright © 2009  cod technologies ltd  www.codtech.com
  • 14. uml class diagram copyright © 2009  cod technologies ltd  www.codtech.com
  • 15. ApplicationTestCase ● test Application in controlled environment ● basic lyfecycle support – onCreate() called after createApplication() – tearDown() calls onDestroy() ● mock Context can be injected ● Application can be terminated with  terminateApplication() copyright © 2009  cod technologies ltd  www.codtech.com
  • 16. ActivityUnitTestCase ● isolated testing of a single Activity ● Activity created with minimal connection to the  system ● mocked dependencies can be injected ● Activity will not participate in the normal  interactions with the system ● some methods should be avoided and will throw  exceptions if called copyright © 2009  cod technologies ltd  www.codtech.com
  • 17. ProviderTestCase2<T> ● isolated testing of a ContentProvider ● uses a MockContentResolver to – access the provider – restricts access to filesystem (db & files) – injects IsolatedContext ● environment managed by setUp() and  tearDown() copyright © 2009  cod technologies ltd  www.codtech.com
  • 18. ServiceTestCase<T> ● framework to test Services ● basic support for lifecycle – onCreate() called after startService(Intent) or  bindService(Intent) – depending on how was started tearDown() calls  appropriate method ● mock objects can be injected by – setApplication() – setContext() copyright © 2009  cod technologies ltd  www.codtech.com
  • 19. AndroidTestCase ● base class that can be extended to support  different requirements ● use this if you need – isolate components – test custom Views – test permissions – access Resources copyright © 2009  cod technologies ltd  www.codtech.com
  • 20. ViewAsserts ● useful assertions about Views – Views are aligned in several ways – ViewGroups contain Views – View is on screen – View has specific screen coordinates copyright © 2009  cod technologies ltd  www.codtech.com
  • 21. TouchUtils ● use these methods to generate touch events ● clickView() to simulate touching ● drag...() to touch and drag ● longClick() for touching and holding ● scroll...() to simulate different scrolling ● tapView() to touch and release quickly copyright © 2009  cod technologies ltd  www.codtech.com
  • 22. android.test.mock all classes has non­functional methods ● MockApplication ● MockContentResolver ● MockContext ● MockDialogInterface ● MockPackageManager ● MockResources copyright © 2009  cod technologies ltd  www.codtech.com
  • 24. after this section you will after this section you will... ● be able to create a project  and its corresponding tests  project ● apply test driven  development techniques ● get acquainted with android  tests copyright © 2009  cod technologies ltd  www.codtech.com
  • 25. design converts temperatures from celsius e r us to e n th whehrenheit a d an if the fa rsa err re' e- e t vicen vers one or s a nd atur e in dis pla sh o uld temper ther is (O ) ye d be e o he ld th re fie ed updat lly m atica auto we l eave f or s p ac keyb e o ar d copyright © 2009  cod technologies ltd  www.codtech.com
  • 26. create project Choose the  build target copyright © 2009  cod technologies ltd  www.codtech.com
  • 27. create test project always create a  test project other values are  automatically  selected copyright © 2009  cod technologies ltd  www.codtech.com
  • 28. create test case to create the test for  the Activity we use  ActivityInstrument ationTestCase2<T> create method  stubs the Activity as the  class under test copyright © 2009  cod technologies ltd  www.codtech.com
  • 29. check generated test case /** * Copyright © 2009 COD Technologies Ltd. All rights reserved. */ package com.codtech.android.training.tctdd1.test; import android.test.ActivityInstrumentationTestCase2; import adjust stub  com.codtech.android.training.tctdd1.TemperatureConverterActivity; constructor to pass  required arguments  public class to super TemperatureConverterActivityTests extends ActivityInstrumentationTestCase2<TemperatureConverterActivity> { /** * @param name */ public TemperatureConverterActivityTests(String name) { super("com.codtech.android.training.tctdd1", TemperatureConverterActivity.class); setName(name); } // setUp() and tearDown() not showed } copyright © 2009  cod technologies ltd  www.codtech.com
  • 30. setUp /* (non-Javadoc) * @see android.test.ActivityInstrumentationTestCase2#setUp() */ these constants are  protected void setUp() throws Exception { not yet created, we  super.setUp(); need to add the  Views and Ids to the  final TemperatureConverterActivity activity = getActivity(); layout celsius = (EditText)activity.findViewById( com.codtech.android.training.tctdd1.R.id.celsius); fahrenheit = (EditText)activity.findViewById( com.codtech.android.training.tctdd1.R.id.fahrenheit); } create fields  when necessary copyright © 2009  cod technologies ltd  www.codtech.com
  • 31. layout Ids should  satisfy  previous  requirements copyright © 2009  cod technologies ltd  www.codtech.com
  • 32. add some UI tests @SmallTest public void testSimpleCreate() { assertNotNull(getActivity()); assertNotNull(celsius); assertNotNull(fahrenheit); ViewAsserts.assertOnScreen(fahrenheit.getRootView(), celsius); ViewAsserts.assertOnScreen(celsius.getRootView(), fahrenheit); } @SmallTest public void testAlignment() { ViewAsserts.assertRightAligned(celsius, fahrenheit); ViewAsserts.assertLeftAligned(celsius, fahrenheit); } @SmallTest public void testFiledsStartEmpty() { assertTrue("Celsius field starts not empty", "".equals(celsius.getText().toString())); assertTrue("Fahrenheit field starts not empty", "".equals(fahrenheit.getText().toString())); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 33. now some functional tests we run the test in the  UI thread @UiThreadTest public void testFahrenheitToCelsiusConversion() { we don't have a  celsius.clear(); class implementing  fahrenheit.clear(); setNumber(),  getNumber() and  final double f = 32.5; clear() so we will be  creating it soon fahrenheit.requestFocus(); fahrenheit.setNumber(f); celsius.requestFocus(); final double c = TemperatureConverter.fahrenheitToCelsius(f); final double cr = celsius.getNumber(); final double delta = Math.abs(c - cr); final String msg = "" + f + "F should be " + c + "C but was " + cr + " (delta " + delta + ")"; assertTrue(msg, delta < 0.005); } we don't have a  TemperatureConverter  either copyright © 2009  cod technologies ltd  www.codtech.com
  • 34. and more tests don't run this test  in UI thread @SmallTest public void testCelsiusToFahrenheitConversion() { final double c = -105.35; TouchUtils.tapView(this, celsius); create method stub in  sendKeys("MINUS 1 0 5 PERIOD 3 5"); TemperatureConverter final double cr = celsius.getNumber(); assertEquals("Send keys should have set " + c + " but set " + cr, c, cr); final double f = TemperatureConverter.celsiusToFahrenheit(c); final double fr = fahrenheit.getNumber(); final double delta = Math.abs(f - fr); final String msg = "" + c + "C should be " + f + "F but was " + fr + " (delta " + delta + ")"; assertTrue(msg, delta < 0.005); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 35. create EditNumber class create a  new  package for  views extend  EditText once we create  EditNumber we  should refactor  our main layout  and fields copyright © 2009  cod technologies ltd  www.codtech.com
  • 36. create TemperatureConverter class copyright © 2009  cod technologies ltd  www.codtech.com
  • 37. create a TestCase create  stubs test  TemperatureConverter copyright © 2009  cod technologies ltd  www.codtech.com
  • 38. select methods to test copyright © 2009  cod technologies ltd  www.codtech.com
  • 39. complete actual tests public void testFahrenheitToCelsius() { for (double c: conversionTableDouble.keySet()) { final double f = conversionTableDouble.get(c); final double cr = TemperatureConverter.fahrenheitToCelsius(f); final double delta = Math.abs(c - cr); final String msg = "" + f + "F should be " + c + "C but is " + cr + " (delta " + delta + ")"; assertTrue(msg, delta < 0.0001); } } public void testCelsiusToFahrenheit() { for (double c: conversionTableDouble.keySet()) { final double f = conversionTableDouble.get(c); final double fr = TemperatureConverter.celsiusToFahrenheit(c); final double delta = Math.abs(f - fr); final String msg = "" + c + "C should be " + f + "F but is " + fr + " (delta " + delta + ")" ; assertTrue(msg, delta < 0.0001); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 40. test exceptions public void testAbsoluteZeroCelsius() { Exception e = null; try { TemperatureConverter.celsiusToFahrenheit(-274); } catch (RuntimeException re) { } assertNotNull("Absolute zero C not detected", e); } public void testAbsoluteZeroFahrenheit() { Exception e = null; try { TemperatureConverter.fahrenheitToCelsius(-460); } catch (RuntimeException re) { e = re; } assertNotNull("Absolute zero F not detected", e); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 41. conversion table ● simple conversion table to run several tests private static final HashMap<Double, Double> conversionTableDouble = new HashMap<Double, Double>(); static { // initialize (c, f) pairs conversionTableDouble.put(0.0, 32.0); conversionTableDouble.put(100.0, 212.0); conversionTableDouble.put(-1.0, 30.20); conversionTableDouble.put(-100.0, -148.0); conversionTableDouble.put(32.0, 89.60); conversionTableDouble.put(-40.0, -40.0); conversionTableDouble.put(-273.0, -459.40); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 42. run tests conversion tests fail  because we haven't  implemented it yet copyright © 2009  cod technologies ltd  www.codtech.com
  • 43. TemperatureConverter package com.codtech.android.training.tctdd1; public class TemperatureConverter { public static final double ABSOLUTE_ZERO_C = -273.0d; public static final double ABSOLUTE_ZERO_F = -459.4d; private static final String ERROR_MESSAGE_BELOW_ZERO_FMT = "Invalid temperature: %.2f%c below absolute zero"; public static double celsiusToFahrenheit(double c) { if (c < ABSOLUTE_ZERO_C) { throw new RuntimeException( String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, c, 'C')); } return (c * 1.8d + 32); } public static double fahrenheitToCelsius(double f) { if (f < ABSOLUTE_ZERO_F) { throw new RuntimeException( String.format(ERROR_MESSAGE_BELOW_ZERO_FMT, f, 'F')); } return ((f - 32) / 1.8d); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 44. run tests tests fail now because we  are doing the conversion  right but we are invoking  conversion tests  empty methods in  succeded EditNumber that don't  update the ui copyright © 2009  cod technologies ltd  www.codtech.com
  • 45. implement EditNumber methods package com.codtech.android.training.tctdd1.view; import android.content.Context; import android.util.AttributeSet; import android.widget.EditText; public class EditNumber extends EditText { public EditNumber(Context context) { super(context); } public EditNumber(Context context, AttributeSet attrs) { super(context, attrs); } convenience methods  delegating to EditText public void clear() { setText(""); } public void setNumber(double f) { setText(Double.toString(f)); } public double getNumber() { return Double.valueOf(getText().toString()); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 46. run tests a NumberFormatException  because we are not changing  the other field when some  new temperature is entered  and thus the field is empty copyright © 2009  cod technologies ltd  www.codtech.com
  • 47. onCreate /** Called when the activity is first created. */ @SuppressWarnings("unchecked") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); add change listener  celsius = (EditNumber)findViewById(R.id.celsius); to these fields fahrenheit = (EditNumber)findViewById(R.id.fahrenheit); try { Class[] args = new Class[] { double.class }; celsius.addTextChangedListener( new TemperatureChangedWatcher(fahrenheit, TemperatureConverter.class.getMethod( "celsiusToFahrenheit", args))); fahrenheit.addTextChangedListener( new TemperatureChangedWatcher(celsius, TemperatureConverter.class.getMethod( "fahrenheitToCelsius", args))); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 48. TemperatureChangedWatcher private static class TemperatureChangedWatcher implements TextWatcher { private EditNumber dest; private Method convert; public TemperatureChangedWatcher(EditNumber dest, Method convert) { this.dest = dest; this.convert = convert; } @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (!dest.hasWindowFocus() || dest.hasFocus() || s == null ) { return; } // continued ... copyright © 2009  cod technologies ltd  www.codtech.com
  • 49. TemperatureChangedWatcher final String ss = s.toString(); if ( "".equals(ss) ) { dest.clear(); return; } try { final double result = (Double) convert.invoke(TemperatureConverter.class, Double.parseDouble(ss)); // display only 2 decimals dest.setNumber(Math.rint(result*100)/100); } catch (NumberFormatException e) { // WARNING // this is generated while a number is entered, // for example just a -' so we don't want to show the error } catch (Exception e) { dest.setError(e.getCause().getLocalizedMessage()); } } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 50. tests succeed copyright © 2009  cod technologies ltd  www.codtech.com
  • 51. temperature converter converts temperatures from celsius e r us to e n th whehrenheit a d an if the fa rsa err re' e- e t vicen vers one or s a nd atur e in dis pla sh o uld temper ther is (O ) ye d be e o he ld th re fie ed updat lly m atica auto we l eave f or s p ac keyb e o ar d copyright © 2009  cod technologies ltd  www.codtech.com
  • 52. instrumentation ● Dev Tools → Instrumentation → TCTDD1 Tests copyright © 2009  cod technologies ltd  www.codtech.com
  • 53. eclipse ● TCTDD1Test → Run As → Android JUnit Test copyright © 2009  cod technologies ltd  www.codtech.com
  • 54. command line diego@bruce:~$ adb -e shell am instrument -w -e class com.codtech.android.training.tctdd1.test.TemperatureCo nverterActivityTests com.codtech.android.training.tctdd1.test/android.test. InstrumentationTestRunner com.codtech.android.training.tctdd1.test.TemperatureCo nverterActivityTests:..... Test results for InstrumentationTestRunner=..... Time: 5.564 OK (5 tests) copyright © 2009  cod technologies ltd  www.codtech.com
  • 55. EditNumberTests AndroidTestCase copyright © 2009  cod technologies ltd  www.codtech.com
  • 56. select methods to test copyright © 2009  cod technologies ltd  www.codtech.com
  • 57. constructor and setUp /** * @param name */ public EditNumberTests(String name) { super(); setName(name); } creating a mock  context /* (non-Javadoc) * @see android.test.AndroidTestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); mockContext = new IsolatedContext(new MockContentResolver(), getContext()); editNumber = new EditNumber(mockContext); editNumber.setFocusable(true); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 58. complete actual tests /** * Test method for EditNumber#EditNumber(android.content.Context) */ public void testEditNumberContext() { assertNotNull(new EditNumber(mockContext)); } /** * Test method for EditNumber#EditNumber(Context, AttributeSet) */ public void testEditNumberContextAttributeSet() { // TODO // use a real AttributeSet for this test not null assertNotNull(new EditNumber(mockContext, null)); } /** * Test method for EditNumber#clear() */ public void testClear() { editNumber.setText("1234"); editNumber.clear(); assertEquals("editNumber should have been cleared", "", editNumber.getText().toString()); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 59. complete actual tests public void testSetNumber() { final double d = 1.23d; editNumber.setNumber(d); final double dr = editNumber.getNumber(); final String msg = "editNumber should be " + d + " but is " + dr; assertEquals(msg, d, dr); } public void testGetNumber() { final double d = 0.98d; final String ds = Double.toString(d); editNumber.setText(ds); final double dr = editNumber.getNumber(); final String msg = "editNumber should be " + ds + " but is " + dr; assertEquals(msg, d, dr); } copyright © 2009  cod technologies ltd  www.codtech.com
  • 60. input test public class TemperatureConverterActivityTests extends ActivityInstrumentationTestCase2<TemperatureConverterActivity> { // … @SmallTest public void testInputFilter() { TouchUtils.tapView(this, celsius); final Double n = -1.234d; sendKeys("MINUS 1 PERIOD 2 PERIOD 3 PERIOD 4"); Object nr = null; try { nr = celsius.getNumber(); } catch (NumberFormatException e) { nr = celsius.getText(); } final String msg = "-1.2.3.4 should be filtered to " + n + " but is " + nr; assertEquals(msg, n, nr); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 61. input filter public class EditNumber extends EditText { // … invoke init() from  constructors /** * Initialization. * Set filter. * */ private void init() { // DigistKeyListener.getInstance(true, true) returns an // instance that accepts digits, sign and decimal point final InputFilter[] filters = new InputFilter[] { DigitsKeyListener.getInstance(true, true) }; setFilters(filters); } } copyright © 2009  cod technologies ltd  www.codtech.com
  • 62. resources ● http://dtmilano.blogspot.com ● http://easymock.org ● http://code.google.com/p/hamcrest (matchers) ● http://mockito.org/ ● http://developer.android.com/guide/developing/t ools/monkey.html (ui exerciser) ● http://ricston.com/ricston­training­for­android/ ● http://android.codtech.com copyright © 2009  cod technologies ltd  www.codtech.com
  • 63. “If things seem under control,  you're not going fast enough.” ­­ Mario Andretti copyright © 2009  cod technologies ltd  www.codtech.com
  • 64. thank you testing on android london, december 2009 diego torres milano [email protected] copyright © 2009  cod technologies ltd  www.codtech.com