19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.test;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Activity;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Method;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides functional testing of a single activity.  The activity under test will
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and you will then be able to manipulate your Activity directly.
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Other options supported by this test case include:
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>You can run any test method on the UI thread (see {@link android.test.UiThreadTest}).</li>
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>You can inject custom Intents into your Activity (see
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setActivityIntent(Intent)}).</li>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This class replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated.
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * New tests should be written using this base class.
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}.
403aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez *
413aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <div class="special reference">
423aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <h3>Developer Guides</h3>
433aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <p>For more information about application testing, read the
443aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
453aef8e1d1b2f0b87d470bcccf37ba4ebb6560c45Joe Fernandez * </div>
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ActivityInstrumentationTestCase2<T extends Activity>
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        extends ActivityTestCase {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Class<T> mActivityClass;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mInitialTouchMode = false;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Intent mActivityIntent = null;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5490762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * Creates an {@link ActivityInstrumentationTestCase2}.
5590762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     *
5690762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * @param pkg ignored - no longer in use.
5790762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * @param activityClass The activity to test. This must be a class in the instrumentation
5890762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * targetPackage specified in the AndroidManifest.xml
5990762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     *
6090762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * @deprecated use {@link #ActivityInstrumentationTestCase2(Class)} instead
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6290762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot    @Deprecated
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
6490762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot        this(activityClass);
6590762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot    }
6690762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot
6790762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot    /**
6890762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * Creates an {@link ActivityInstrumentationTestCase2}.
6990762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     *
7090762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * @param activityClass The activity to test. This must be a class in the instrumentation
7190762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     * targetPackage specified in the AndroidManifest.xml
7290762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot     */
7390762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot    public ActivityInstrumentationTestCase2(Class<T> activityClass) {
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActivityClass = activityClass;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Get the Activity under test, starting it if necessary.
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * For each test method invocation, the Activity will not actually be created until the first
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * time this method is called.
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If you wish to provide custom setup values to your Activity, you may call
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setActivityIntent(Intent)} and/or {@link #setActivityInitialTouchMode(boolean)}
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * before your first call to getActivity().  Calling them after your Activity has
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * started will have no effect.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If your test method is annotated with {@link android.test.UiThreadTest}, then your Activity
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be started automatically just before your test method is run.  You still call this
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method in order to get the Activity under test.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the Activity under test
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public T getActivity() {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Activity a = super.getActivity();
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (a == null) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // set initial touch mode
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            getInstrumentation().setInTouchMode(mInitialTouchMode);
10190762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot            final String targetPackage = getInstrumentation().getTargetContext().getPackageName();
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // inject custom intent, if provided
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mActivityIntent == null) {
10490762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot                a = launchActivity(targetPackage, mActivityClass, null);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
10690762d35a99e32ed22cdfb1f81252544ee22e30bBrett Chabot                a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setActivity(a);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return (T) a;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call this method before the first call to {@link #getActivity} to inject a customized Intent
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * into the Activity under test.
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If you do not call this, the default intent will be provided.  If you call this after
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * your Activity has been started, it will have no effect.
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setActivityIntent(Intent)} from {@link #setUp()}.
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default Intent (if this method is not called) is:
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  action = {@link Intent#ACTION_MAIN}
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * All other fields are null or empty.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param i The Intent to start the Activity with, or null to reset to the default Intent.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setActivityIntent(Intent i) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mActivityIntent = i;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call this method before the first call to {@link #getActivity} to set the initial touch
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode for the Activity under test.
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>If you do not call this, the touch mode will be false.  If you call this after
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * your Activity has been started, it will have no effect.
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setActivityInitialTouchMode(boolean)} from {@link #setUp()}.
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param initialTouchMode true if the Activity should be placed into "touch mode" when started
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setActivityInitialTouchMode(boolean initialTouchMode) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInitialTouchMode = initialTouchMode;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void setUp() throws Exception {
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.setUp();
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1563fe3f7328fb4a6f5e067eedc76086dd7b44ffc25Rodrigo Damazio Bovendorp        mInitialTouchMode = false;
1573fe3f7328fb4a6f5e067eedc76086dd7b44ffc25Rodrigo Damazio Bovendorp        mActivityIntent = null;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void tearDown() throws Exception {
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Finish the Activity off (unless was never launched anyway)
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Activity a = super.getActivity();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (a != null) {
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            a.finish();
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setActivity(null);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Scrub out members - protects against memory leaks in the case where someone
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // creates a non-static inner class (thus referencing the test case) and gives it to
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // someone else to hold onto
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        scrubClass(ActivityInstrumentationTestCase2.class);
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.tearDown();
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Runs the current unit test. If the unit test is annotated with
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.test.UiThreadTest}, force the Activity to be created before switching to
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the UI thread.
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void runTest() throws Throwable {
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Method method = getClass().getMethod(getName(), (Class[]) null);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (method.isAnnotationPresent(UiThreadTest.class)) {
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                getActivity();
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (Exception e) {
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // eat the exception here; super.runTest() will catch it again and handle it properly
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.runTest();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
196