2009-03-03 19:31:44 -08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package android.test;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Intent;
|
|
|
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class provides functional testing of a single activity. The activity under test will
|
|
|
|
* be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
|
|
|
|
* and you will then be able to manipulate your Activity directly.
|
|
|
|
*
|
|
|
|
* <p>Other options supported by this test case include:
|
|
|
|
* <ul>
|
|
|
|
* <li>You can run any test method on the UI thread (see {@link android.test.UiThreadTest}).</li>
|
|
|
|
* <li>You can inject custom Intents into your Activity (see
|
|
|
|
* {@link #setActivityIntent(Intent)}).</li>
|
|
|
|
* </ul>
|
|
|
|
*
|
|
|
|
* <p>This class replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated.
|
|
|
|
* New tests should be written using this base class.
|
|
|
|
*
|
|
|
|
* <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}.
|
|
|
|
*/
|
|
|
|
public abstract class ActivityInstrumentationTestCase2<T extends Activity>
|
|
|
|
extends ActivityTestCase {
|
|
|
|
String mPackage;
|
|
|
|
Class<T> mActivityClass;
|
|
|
|
boolean mInitialTouchMode = false;
|
|
|
|
Intent mActivityIntent = null;
|
|
|
|
|
|
|
|
/**
|
2009-04-21 11:54:14 -07:00
|
|
|
* <b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
|
|
|
|
* package hosting the activity to be launched, which is specified in the AndroidManifest.xml
|
|
|
|
* file. This is not necessarily the same as the java package name.
|
|
|
|
*
|
|
|
|
* @param pkg The package hosting the activity to be launched.
|
2009-03-03 19:31:44 -08:00
|
|
|
* @param activityClass The activity to test.
|
|
|
|
*/
|
|
|
|
public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
|
|
|
|
mPackage = pkg;
|
|
|
|
mActivityClass = activityClass;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the Activity under test, starting it if necessary.
|
|
|
|
*
|
|
|
|
* For each test method invocation, the Activity will not actually be created until the first
|
|
|
|
* time this method is called.
|
|
|
|
*
|
|
|
|
* <p>If you wish to provide custom setup values to your Activity, you may call
|
|
|
|
* {@link #setActivityIntent(Intent)} and/or {@link #setActivityInitialTouchMode(boolean)}
|
|
|
|
* before your first call to getActivity(). Calling them after your Activity has
|
|
|
|
* started will have no effect.
|
|
|
|
*
|
|
|
|
* <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
|
|
|
|
* If your test method is annotated with {@link android.test.UiThreadTest}, then your Activity
|
|
|
|
* will be started automatically just before your test method is run. You still call this
|
|
|
|
* method in order to get the Activity under test.
|
|
|
|
*
|
|
|
|
* @return the Activity under test
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public T getActivity() {
|
|
|
|
Activity a = super.getActivity();
|
|
|
|
if (a == null) {
|
|
|
|
// set initial touch mode
|
|
|
|
getInstrumentation().setInTouchMode(mInitialTouchMode);
|
|
|
|
// inject custom intent, if provided
|
|
|
|
if (mActivityIntent == null) {
|
|
|
|
a = launchActivity(mPackage, mActivityClass, null);
|
|
|
|
} else {
|
|
|
|
a = launchActivityWithIntent(mPackage, mActivityClass, mActivityIntent);
|
|
|
|
}
|
|
|
|
setActivity(a);
|
|
|
|
}
|
|
|
|
return (T) a;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call this method before the first call to {@link #getActivity} to inject a customized Intent
|
|
|
|
* into the Activity under test.
|
|
|
|
*
|
|
|
|
* <p>If you do not call this, the default intent will be provided. If you call this after
|
|
|
|
* your Activity has been started, it will have no effect.
|
|
|
|
*
|
|
|
|
* <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
|
|
|
|
* If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
|
|
|
|
* {@link #setActivityIntent(Intent)} from {@link #setUp()}.
|
|
|
|
*
|
|
|
|
* <p>The default Intent (if this method is not called) is:
|
|
|
|
* action = {@link Intent#ACTION_MAIN}
|
|
|
|
* flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
|
|
|
|
* All other fields are null or empty.
|
|
|
|
*
|
|
|
|
* @param i The Intent to start the Activity with, or null to reset to the default Intent.
|
|
|
|
*/
|
|
|
|
public void setActivityIntent(Intent i) {
|
|
|
|
mActivityIntent = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Call this method before the first call to {@link #getActivity} to set the initial touch
|
|
|
|
* mode for the Activity under test.
|
|
|
|
*
|
|
|
|
* <p>If you do not call this, the touch mode will be false. If you call this after
|
|
|
|
* your Activity has been started, it will have no effect.
|
|
|
|
*
|
|
|
|
* <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
|
|
|
|
* If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
|
|
|
|
* {@link #setActivityInitialTouchMode(boolean)} from {@link #setUp()}.
|
|
|
|
*
|
|
|
|
* @param initialTouchMode true if the Activity should be placed into "touch mode" when started
|
|
|
|
*/
|
|
|
|
public void setActivityInitialTouchMode(boolean initialTouchMode) {
|
|
|
|
mInitialTouchMode = initialTouchMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void setUp() throws Exception {
|
|
|
|
super.setUp();
|
|
|
|
|
|
|
|
boolean mInitialTouchMode = false;
|
|
|
|
Intent mActivityIntent = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void tearDown() throws Exception {
|
|
|
|
// Finish the Activity off (unless was never launched anyway)
|
|
|
|
Activity a = super.getActivity();
|
|
|
|
if (a != null) {
|
|
|
|
a.finish();
|
|
|
|
setActivity(null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scrub out members - protects against memory leaks in the case where someone
|
|
|
|
// creates a non-static inner class (thus referencing the test case) and gives it to
|
|
|
|
// someone else to hold onto
|
|
|
|
scrubClass(ActivityInstrumentationTestCase2.class);
|
|
|
|
|
|
|
|
super.tearDown();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs the current unit test. If the unit test is annotated with
|
|
|
|
* {@link android.test.UiThreadTest}, force the Activity to be created before switching to
|
|
|
|
* the UI thread.
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
protected void runTest() throws Throwable {
|
|
|
|
try {
|
|
|
|
Method method = getClass().getMethod(getName(), (Class[]) null);
|
|
|
|
if (method.isAnnotationPresent(UiThreadTest.class)) {
|
|
|
|
getActivity();
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
// eat the exception here; super.runTest() will catch it again and handle it properly
|
|
|
|
}
|
|
|
|
super.runTest();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|