How do you test an Android application across multiple Activities?
I feel a bit awkward about answering my own bounty question, but here it is...
I've searched high and low on this and can't believe there is no answer published anywhere. I have come very close. I can definitely run tests that span activities now, but my implementation seems to have some timing issues where the tests don't always pass reliably. This is the only example that I know of that tests across multiple activities successfully. Hopefully my extraction and anonymizing of it did not introduce errors. This is a simplistic test where I type a username and password into a login activity, and then observe a proper welcome message is shown on a different "welcome" activity:
package com.mycompany;import android.app.*;import android.content.*;import android.test.*;import android.test.suitebuilder.annotation.*;import android.util.*;import android.view.*;import android.widget.*;import static org.hamcrest.core.Is.*;import static org.hamcrest.core.IsNull.*;import static org.hamcrest.core.IsInstanceOf.instanceOf;import static org.junit.Assert.*;import static com.mycompany.R.id.*;public class LoginTests extends InstrumentationTestCase { @MediumTest public void testAValidUserCanLogIn() { Instrumentation instrumentation = getInstrumentation(); // Register we are interested in the authentication activiry... Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(AuthenticateActivity.class.getName(), null, false); // Start the authentication activity as the first activity... Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClassName(instrumentation.getTargetContext(), AuthenticateActivity.class.getName()); instrumentation.startActivitySync(intent); // Wait for it to start... Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); assertThat(currentActivity, is(notNullValue())); // Type into the username field... View currentView = currentActivity.findViewById(username_field); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(EditText.class)); TouchUtils.clickView(this, currentView); instrumentation.sendStringSync("MyUsername"); // Type into the password field... currentView = currentActivity.findViewById(password_field); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(EditText.class)); TouchUtils.clickView(this, currentView); instrumentation.sendStringSync("MyPassword"); // Register we are interested in the welcome activity... // this has to be done before we do something that will send us to that // activity... instrumentation.removeMonitor(monitor); monitor = instrumentation.addMonitor(WelcomeActivity.class.getName(), null, false); // Click the login button... currentView = currentActivity.findViewById(login_button; assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(Button.class)); TouchUtils.clickView(this, currentView); // Wait for the welcome page to start... currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); assertThat(currentActivity, is(notNullValue())); // Make sure we are logged in... currentView = currentActivity.findViewById(welcome_message); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(TextView.class)); assertThat(((TextView)currentView).getText().toString(), is("Welcome, MyUsername!")); }}
This code is obviously not very readable. I have actually extracted it into a simple library with an English-like API so I can just say things like this:
type("myUsername").intoThe(username_field);click(login_button);
I've tested to a depth of about 4 activities and am satisfied that the approach works though as I said, there appears to be an occasional timing issue I have not completely figured out. I am still interested in hearing of any other ways of testing across activities.
Take a look at Robotium
'a open-source test framework created to make automatic black-box testing of Android applications significantly faster and easier than what is possible with Android instrumentation tests out-of-the-box.'
Homepage: http://www.robotium.org/
Source:http://github.com/jayway/robotium
Please note that the Robotium project is maintained by the company I work for
You could always use Robotium. It supports blackbox testing just like Selenium but for Android. You will find it at Robotium.org