Home | History | Annotate | Download | only in test
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.test;
     18 
     19 import android.app.Activity;
     20 import android.content.Intent;
     21 
     22 import java.lang.reflect.Method;
     23 
     24 /**
     25  * This class provides functional testing of a single activity.  The activity under test will
     26  * be created using the system infrastructure (by calling InstrumentationTestCase.launchActivity())
     27  * and you will then be able to manipulate your Activity directly.
     28  *
     29  * <p>Other options supported by this test case include:
     30  * <ul>
     31  * <li>You can run any test method on the UI thread (see {@link android.test.UiThreadTest}).</li>
     32  * <li>You can inject custom Intents into your Activity (see
     33  * {@link #setActivityIntent(Intent)}).</li>
     34  * </ul>
     35  *
     36  * <p>This class replaces {@link android.test.ActivityInstrumentationTestCase}, which is deprecated.
     37  * New tests should be written using this base class.
     38  *
     39  * <p>If you prefer an isolated unit test, see {@link android.test.ActivityUnitTestCase}.
     40  *
     41  * @deprecated Use
     42  * <a href="{@docRoot}reference/android/support/test/rule/ActivityTestRule.html">
     43  * ActivityTestRule</a> instead. New tests should be written using the
     44  * <a href="{@docRoot}tools/testing-support-library/index.html">Android Testing Support Library</a>.
     45  */
     46 @Deprecated
     47 public abstract class ActivityInstrumentationTestCase2<T extends Activity>
     48         extends ActivityTestCase {
     49     Class<T> mActivityClass;
     50     boolean mInitialTouchMode = false;
     51     Intent mActivityIntent = null;
     52 
     53     /**
     54      * Creates an {@link ActivityInstrumentationTestCase2}.
     55      *
     56      * @param pkg ignored - no longer in use.
     57      * @param activityClass The activity to test. This must be a class in the instrumentation
     58      * targetPackage specified in the AndroidManifest.xml
     59      *
     60      * @deprecated use {@link #ActivityInstrumentationTestCase2(Class)} instead
     61      */
     62     @Deprecated
     63     public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
     64         this(activityClass);
     65     }
     66 
     67     /**
     68      * Creates an {@link ActivityInstrumentationTestCase2}.
     69      *
     70      * @param activityClass The activity to test. This must be a class in the instrumentation
     71      * targetPackage specified in the AndroidManifest.xml
     72      */
     73     public ActivityInstrumentationTestCase2(Class<T> activityClass) {
     74         mActivityClass = activityClass;
     75     }
     76 
     77     /**
     78      * Get the Activity under test, starting it if necessary.
     79      *
     80      * For each test method invocation, the Activity will not actually be created until the first
     81      * time this method is called.
     82      *
     83      * <p>If you wish to provide custom setup values to your Activity, you may call
     84      * {@link #setActivityIntent(Intent)} and/or {@link #setActivityInitialTouchMode(boolean)}
     85      * before your first call to getActivity().  Calling them after your Activity has
     86      * started will have no effect.
     87      *
     88      * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
     89      * If your test method is annotated with {@link android.test.UiThreadTest}, then your Activity
     90      * will be started automatically just before your test method is run.  You still call this
     91      * method in order to get the Activity under test.
     92      *
     93      * @return the Activity under test
     94      */
     95     @Override
     96     public T getActivity() {
     97         Activity a = super.getActivity();
     98         if (a == null) {
     99             // set initial touch mode
    100             getInstrumentation().setInTouchMode(mInitialTouchMode);
    101             final String targetPackage = getInstrumentation().getTargetContext().getPackageName();
    102             // inject custom intent, if provided
    103             if (mActivityIntent == null) {
    104                 a = launchActivity(targetPackage, mActivityClass, null);
    105             } else {
    106                 a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);
    107             }
    108             setActivity(a);
    109         }
    110         return (T) a;
    111     }
    112 
    113     /**
    114      * Call this method before the first call to {@link #getActivity} to inject a customized Intent
    115      * into the Activity under test.
    116      *
    117      * <p>If you do not call this, the default intent will be provided.  If you call this after
    118      * your Activity has been started, it will have no effect.
    119      *
    120      * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
    121      * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
    122      * {@link #setActivityIntent(Intent)} from {@link #setUp()}.
    123      *
    124      * <p>The default Intent (if this method is not called) is:
    125      *  action = {@link Intent#ACTION_MAIN}
    126      *  flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
    127      * All other fields are null or empty.
    128      *
    129      * @param i The Intent to start the Activity with, or null to reset to the default Intent.
    130      */
    131     public void setActivityIntent(Intent i) {
    132         mActivityIntent = i;
    133     }
    134 
    135     /**
    136      * Call this method before the first call to {@link #getActivity} to set the initial touch
    137      * mode for the Activity under test.
    138      *
    139      * <p>If you do not call this, the touch mode will be false.  If you call this after
    140      * your Activity has been started, it will have no effect.
    141      *
    142      * <p><b>NOTE:</b> Activities under test may not be started from within the UI thread.
    143      * If your test method is annotated with {@link android.test.UiThreadTest}, then you must call
    144      * {@link #setActivityInitialTouchMode(boolean)} from {@link #setUp()}.
    145      *
    146      * @param initialTouchMode true if the Activity should be placed into "touch mode" when started
    147      */
    148     public void setActivityInitialTouchMode(boolean initialTouchMode) {
    149         mInitialTouchMode = initialTouchMode;
    150     }
    151 
    152     @Override
    153     protected void setUp() throws Exception {
    154         super.setUp();
    155 
    156         mInitialTouchMode = false;
    157         mActivityIntent = null;
    158     }
    159 
    160     @Override
    161     protected void tearDown() throws Exception {
    162         // Finish the Activity off (unless was never launched anyway)
    163         Activity a = super.getActivity();
    164         if (a != null) {
    165             a.finish();
    166             setActivity(null);
    167         }
    168 
    169         // Scrub out members - protects against memory leaks in the case where someone
    170         // creates a non-static inner class (thus referencing the test case) and gives it to
    171         // someone else to hold onto
    172         scrubClass(ActivityInstrumentationTestCase2.class);
    173 
    174         super.tearDown();
    175     }
    176 
    177     /**
    178      * Runs the current unit test. If the unit test is annotated with
    179      * {@link android.test.UiThreadTest}, force the Activity to be created before switching to
    180      * the UI thread.
    181      */
    182     @Override
    183     protected void runTest() throws Throwable {
    184         try {
    185             Method method = getClass().getMethod(getName(), (Class[]) null);
    186             if (method.isAnnotationPresent(UiThreadTest.class)) {
    187                 getActivity();
    188             }
    189         } catch (Exception e) {
    190             // eat the exception here; super.runTest() will catch it again and handle it properly
    191         }
    192         super.runTest();
    193     }
    194 
    195 }
    196