blob: c4bcf312ad9cc4a6aaeab3206466ac480b5ab111 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.test;
18
19import android.app.Activity;
20import android.content.Intent;
21
22import 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}.
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080040 *
41 * <div class="special reference">
42 * <h3>Developer Guides</h3>
43 * <p>For more information about application testing, read the
44 * <a href="{@docRoot}guide/topics/testing/index.html">Testing</a> developer guide.</p>
45 * </div>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 */
47public abstract class ActivityInstrumentationTestCase2<T extends Activity>
48 extends ActivityTestCase {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 Class<T> mActivityClass;
50 boolean mInitialTouchMode = false;
51 Intent mActivityIntent = null;
52
53 /**
Brett Chabot90762d32010-02-11 20:07:17 -080054 * 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 */
Brett Chabot90762d32010-02-11 20:07:17 -080062 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
Brett Chabot90762d32010-02-11 20:07:17 -080064 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) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 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);
Brett Chabot90762d32010-02-11 20:07:17 -0800101 final String targetPackage = getInstrumentation().getTargetContext().getPackageName();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 // inject custom intent, if provided
103 if (mActivityIntent == null) {
Brett Chabot90762d32010-02-11 20:07:17 -0800104 a = launchActivity(targetPackage, mActivityClass, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 } else {
Brett Chabot90762d32010-02-11 20:07:17 -0800106 a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 }
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
Rodrigo Damazio Bovendorp3fe3f732011-08-01 17:10:58 -0300156 mInitialTouchMode = false;
157 mActivityIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 }
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}