testing hybrid applications 

on android


Joe Bowser
bowserj@apache.org
http://infil00p.org

DISCLAIMER and Thanks


  • You have a wide choice in talks, thanks for dropping by
  • I am not a functional testing expert
  • It's possible that something changed in the last two weeks
  • There will be live demonstration of testing
  • Sorry, these tests are going to be written in Java :(

What is a hybrid application



HYBRID Applications

  • Some or most UI developed in HTML/JS/CSS
  • Have an Icon like Native Apps
  • Found in the App Store like Native Apps
  • Have features not found in regular web applications
  • Framework Examples
    • PhoneGap (Apache Cordova)
    • Chrome Packaged Apps on Mobile
    • Intel AppMobi

WHAT IS FUNCTIONAL TESTING

  • A Black Box testing process testing inputs and outputs
  • Different than White-Box testing or Unit Testing
  • Pure Functional Testing is Manual
  • We're going to do Grey-Box testing




NOBODY RUNS MANUAL TESTS

Testing DONE ON ApacHE CORDOVA


(sorry, JUnit doesn't have a pretty logo)

DEVICE WALL : (2010-2013)

DEVICE WALL


OFF-TOPIC: MEDIC

  • Continuous Integration on Multiple Devices
  • Distributed Testing across Devices
  • Written by Fil Maj - @filmaj
  • Runs JavaScript test suites
  • https://github.com/filmaj/medic

FUNCTIONAL TESTING oN ANDROID


  • Selenium
    • Required its own WebKit bridge
    • WebDriver doesn't work with custom webviews
  • Robotium 
    • Robotium can now do Apache Cordova/PhoneGap applications
    • This happened last month! Yay procrastination! 


  • Set up an Eclipse Project
  • Make sure that Robotium is not in the libs directory
  • Make sure that Robotium is first on the list of JARs to be exported
  • Write tests using JUnit and Robotium

SOURCE CODE OF A TEST

 

    public void testSound()

    {

        solo.waitForWebElement(By.textContent("Audio Play/Record"), 10, false);

        solo.clickOnWebElement(By.textContent("Audio Play/Record"));

        solo.waitForWebElement(By.textContent("Play"), 10, false);

        solo.clickOnWebElement(By.textContent("Play"));

        WebElement result = solo.getWebElement(By.textContent("Running"), 0);

        assertNotNull(result);

    }




ROBOTIUM DEMO

DOWN SIDES OF ROBOTIUM

  • I didn't want to scroll, I wanted to touch
  • Getting Robotium set up is a PITA
  • Seems to require Eclipse
  • Sometimes feels like magic when it does work
  • Frustrating errors about JAR precidence, missing/undefined variables

Advantages of robotium

  • People are using Robotium for testing now
  • Active Development for Robotium
  • Commercial Support for Robotium (i.e. bitbar) 
  • You don't have to roll-your-own test framework

PURITY: DIY TOUCH SIMULATION

  • Java class to simulate Touch Events on Android
  • Not quite done yet 
  • Most likely will be abandoned for Robotium
  • Abandon all hope ye who enter here

SIMULATING TOUCH EVENTS

public void touch(int x, int y)

    {

        int realX = getRealCoord(x);

        int realY = getRealCoord(y);

        long downTime = SystemClock.uptimeMillis();

        // event time MUST be retrieved only by this way!

        long eventTime = SystemClock.uptimeMillis();

        if(!fingerDown)

        {

            MotionEvent downEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);

            inst.sendPointerSync(downEvent);

        }

        MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, realX, realY, 0);

        inst.sendPointerSync(upEvent);

    }

MORE CODE

 

    public void testSound()

    {

        sleep(5000);

        clicker.touch(200, 400);

        sleep(1000);

        clicker.touch(75, 325);

        sleep(10000);

        clicker.touch(75, 400);

        sleep(3000);

    }




PURITY DEMO

DOWNSIDES OF THIS APPROACH

  • Pixels aren't really pixels!
  • We didn't actually test anything!

PIXEL MATH

  public Purity(Context ctx, Instrumentation i)

    {

        inst = i;

        DisplayMetrics display = ctx.getResources().getDisplayMetrics();

        density = display.density;

        width = display.widthPixels;

        height = display.heightPixels;

  }


    private int getRealCoord(int coord)

    {

        return (int) (coord * density);

    }

Advantages

  • This approach is API neutral - Truly Black Box
  • This approach allows for pixel control
  • You know for certain when you touch down, touch move and touch up
  • I don't need to use Eclipse to use this test!

Lessons learned

  • Testing is Hard
  • Testing is Insurance
  • Nobody runs Manual Tests on an Open Source Project
  • There is no silver bullet, combine techniques and code for the best result
  • Write more tests
  • Run the tests that you write

RESOURCES

  • Apache Cordova: http://cordova.apache.org
  • PhoneGap: http://www.phonegap.com
  • Blog: http://infil00p.org/
  • Robotium: https://code.google.com/p/robotium/
  • Demo: https://github.com/infil00p/oscon2013-mobilespec
  • Slides: http://slid.es/bowserj/oscon2013
Made with Slides.com