Friday, August 26, 2011

Android Application Testing Guide: Q&A


Q:I followed your example. I set up the test project in a similar way.
But try to write a TestCase for the utility class from the original
project.
Eclipse says "Class under test does not exist in the current project."

It's kind of reasonable to me, since that class is indeed in another
project.
I only have experienced using JUnit to test normal Java Project where
the test directory is inside the project.

Also, I checked out the two example projects and found there is a
build.properties and build.xml. Is that the reason that you can import
the original class:
"import com.example.i2at.tc.TemperatureConverter;"?

Thanks

Best wishes,
Ryan
Posted by Ryan Huang.

A:If you have imported both projects (main & test) into Eclipse you should have no problems because the versions available at github have the required properties set.
However, if for some reason they were not set properly, this is what you should verify in your test project's Java Build Path -> Libraries




The other files you mentioned are used when you build with ant.

Thursday, August 18, 2011

LinuxCon 2011 North America: Introduction to Android Testing

It was terrific having such a great audience showing a big interest in the topic of my tutorial, asking questions and starting discussions that made the presentation more enjoyable. I really want to thank you all.

For those who missed it, here are the slides that should be available at the Linux Foundation web site any time soon too.

Friday, August 05, 2011

Android Application Testing Guide: Q&A


Q:Diego, if we were to test something that is asynchronous, like in my case I'm wanting to test if a webview loads an URL how would I go about waiting for the webpage to finish loading in my webview ?
Posted by Pedro Veloso.

A:Actually this is a very interesting question as there are many ways and you should be cautious about WebView semantics and how some of the WebViewClient methods are called.

For example onPageFinished may be invoked wether the page was successfully loaded or there was an error. So, you may need a different approach if your intention is to test if an url was successfully loaded.

In this code snippet I'm using a MockWebViewClient to detect error conditions and simply waiting some time for the page to load. We could also iterate over a period of time checking if the value has changed instead of just waiting but we are keeping this as simple as possible. This is also assuming you have an Activity holding the WebView and it has the required getters.


/**
 * 
 */
package com.example.aatg.webview.test;

import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.Suppress;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.example.aatg.webview.AndroidHelloWebViewActivity;

/**
 * @author diego
 *
 */
public class AndroidHelloWebViewActivityTests extends
        ActivityInstrumentationTestCase2<AndroidHelloWebViewActivity> {

    private static final String VALID_URL = "http://developer.android.com";
    private static final String INVALID_URL = "http://invalid.url.doesnotexist987.com";

    private static final long TIMEOUT = 5000;

    private AndroidHelloWebViewActivity mActivity;
    private WebView mWebView;
    private MockWebViewClient mMockWebViewClient;

    /**
     * @param name
     */
    public AndroidHelloWebViewActivityTests() {
        super(AndroidHelloWebViewActivity.class);
    }

    /* (non-Javadoc)
     * @see android.test.ActivityInstrumentationTestCase2#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();
        mActivity = getActivity();
        mWebView = mActivity.getWebView();
        mMockWebViewClient = new MockWebViewClient();
        mWebView.setWebViewClient(mMockWebViewClient);
    }

    /* (non-Javadoc)
     * @see android.test.ActivityInstrumentationTestCase2#tearDown()
     */
    protected void tearDown() throws Exception {
        super.tearDown();
    }

    public final void testLoadValidUrl() {
        assertLoadUrl(VALID_URL);
        assertFalse(mMockWebViewClient.mError);
    }

    public final void testLoadInvalidUrl() {
        assertLoadUrl(INVALID_URL);
        assertTrue(mMockWebViewClient.mError);
    }

    private void assertLoadUrl(String url) {
        mWebView.loadUrl(url);
        sleep();
        assertTrue(!(mWebView.getProgress() < 100));
    }

    private void sleep() {
        try {
            Thread.sleep(TIMEOUT);
        } catch (InterruptedException e) {
            fail("Unexpected timeout");
        }
    }

    private class MockWebViewClient extends WebViewClient {
        boolean mError;

        @Override
        public void onReceivedError(WebView view, int errorCode,
                String description, String failingUrl) {
            mError = true;
        }
    }
}


Hope this helps.

Tuesday, August 02, 2011

Android Application Testing Guide: Q&A

Lately I've been receiving some comments or questions about some of the book's subjects in my email. To help the community the best I think that is preferable that you share your questions here, as comments to this post if you cannot find a post dealing with the same topic. If possible I will answer also here for the benefit of all.