Sunday, December 22, 2013

Testing and debugging GAE Endpoints in Android Studio

This material describes how to test GAE Endpoints code on a local Dev Server in Android Studio.  It expands on the earlier Minimalistic GAE Endpoints in Android Studio post.

Local Dev Server

Starting local Dev Server from Android Studio is easy.  
  • From Maven Projects execute
    • Project-AppEngine/Plugins/appengine/appengine:devserver
Go to http://localhost:8080/ to verify that the project is running.  The browser should display your Project-AppEngine/src/main/webapp/index.html page.

Android Emulator

By default, the local Dev Server refuses all connections except those made through http://localhost:8080/.  Since Android emulator uses a special IP address (10.0.2.2) to connect to your localhost, the easiest way to test GAE endpoints is from the emulator.
Create an Android emulator, or use an existing one.  If you create a new emulator, use Intel Atom (x86) image for better performance.
Start the emulator.  Open a browser tab and connect it to http://10.0.2.2:8080.  If the local Dev Server is running, the browser should display your Project-AppEngine/src/main/webapp/index.html page. 

Test Project Dependencies

Add google-http-client-gson dependency to Project-endpoints/build.gradle
dependencies {
    // ...
    instrumentTestCompile 'com.google.http-client:google-http-client-gson:1.17.0-rc'
}

Test Class

Create TestEndpointTest.java under Project-endpoints/src/instrumentTest/java/com/example/package
public class TestEndpointTest extends AndroidTestCase {
    private static final String DEV_SERVER = "http://10.0.2.2:8080/_ah/api/";
    private static final String TAG = TestEndpointTest.class.getSimpleName();
    private Testendpoint endpoint;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        final Testendpoint.Builder bld = new Testendpoint.Builder(
            AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);
        endpoint = bld.setRootUrl(DEV_SERVER).setGoogleClientRequestInitializer(
            new GoogleClientRequestInitializer() {
                @Override
                public void initialize(AbstractGoogleClientRequest request)
                    throws IOException {
                    request.setDisableGZipContent(true);
                }
            }
        ).build();
    }

    @Override
    protected void tearDown() throws Exception {
        endpoint = null;
        super.tearDown();
    }

    public void testListEntities() throws Exception {
        final CollectionResponseTest list = endpoint.listTest().setLimit(10).execute();
        if (list.getItems() != null) {
            for (final Test t : list.getItems()) {
                Log.d(TAG, "id: " + t.getId() + ", message: " + t.getMessage());
            }
        }
    }
}
TestEndpointTest class initializes the endpoint in its setUp() method. It also has a single test method, testListEntities().  Other tests can be created similarly.

Running Tests

Place the mouse cursor on the body of testListEntities(), right-click and select 
  • Run 'testListEntities()' to run the test
  • Debug 'testListEntities()' to debug the test
When you chose Debug option, you will be debugging the client code running on Android Emulator.  Debugging server code running on the local Dev Server is explained next.

Debugging GAE Endpoints on local Dev Server

Create new Remote Run/Debug Configuration

  1. Open the dialog from Run -> Edit Configurations...
  2. Click + button at the top left corner of the dialog
  3. Select Remote from the drop-down menu
    • This will create a new debug configuration
  4. Name the configuration properly, say DevServer
  5. Copy Command line arguments for running remote JVM
    • the arguments will be used in the next step

Modify pom.xml

  1. Open Project-AppEngine/pom.xml
  2. Locate <groupId>com.google.appengine</groupId> plugin
  3. Under <configuration/> tag add <jvmFlags/> tag.
  4. Under <jvmFalgs/> tag add <jvmFalg/> and paste the command line arguments for running remote JVM. 

The resulting <configuration/> should look something like this:
<configuration>
    <enablejarclasses>false</enablejarclasses>
    <jvmflags>
        <jvmflag>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmflag>
    </jvmflags>
</configuration>
where the contents of the <jvmFlag/> tag comes from the step #5 under Create new Remote Run/Debug Configuration.

Debugging the endpoints

  1. Restart local Dev Server
    • From Maven Projects  execute Project-AppEngine/Plugins/appengine/appengine:devserver
  2. Attach debugger to the Dev Server process
    • Select DevServer under available configurations drop-down menu
    • Click on the Debug 'DevServer' button located on the right hand side of the available configurations drop-down
    • The debugging console should print something like:
      • Connected to the target VM, address: 'localhost:5005', transport: 'socket'
  3. Under Project-AppEngine project, set breakpoint in TestEndpoint.listTest() method
  4. Under Project-endpoints project, run TestEndpointTest.testListEntities() method shown earlier.
  5. At this point, your breakpoint should be hit.

No comments:

Post a Comment