Open GoogleCodeExporter opened 9 years ago
I've noticed that this is only a bug on the emulator but doesn't happen on a
real device. This is what I see:
- Test1 runs to completion successfully
- Test2 fails to run and produces the following exception:
java.lang.RuntimeException: Could not launch intent Intent {
act=android.intent.action.MAIN flg=0x10000000
cmp=com.example.multiactivity/.MainActivity } within 45 seconds. Perhaps the
main thread has not gone idle within a reasonable amount of time? There could
be an animation or something constantly repainting the screen. Or the activity
is doing network calls on creation? See the threaddump logs. For your reference
the last time the event queue was idle before your activity launch request was
1399508271868 and and now the last time the queue went idle was: 1399508277083.
If these numbers are the same your activity might be hogging the event queue.
at
com.google.android.apps.common.testing.testrunner.GoogleInstrumentation.startAct
ivitySync(GoogleInstrumentation.java:277)
at
android.test.InstrumentationTestCase.launchActivityWithIntent(InstrumentationTes
tCase.java:119)
at
android.test.InstrumentationTestCase.launchActivity(InstrumentationTestCase.java
:97)
at
android.test.ActivityInstrumentationTestCase2.getActivity(ActivityInstrumentatio
nTestCase2.java:104)
at com.example.multiactivity.test.MultiTest.setUp(MultiTest.java:22)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at
android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:55
4)
at
com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunne
r.onStart(GoogleInstrumentationTestRunner.java:167)
at
android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701)
Original comment by jie...@xero.com
on 8 May 2014 at 12:19
We were seeing this issue also on real devices. Luigi's commit fixes it for us.
Original comment by sschuberth
on 8 May 2014 at 1:58
I'll attach a dummy project which reproduces the problem as soon as I can.
Original comment by luigimas...@gmail.com
on 8 May 2014 at 2:34
I'm currently working around the issue by calling Espresso.pressBack() on
tearDown(). This is obviously just a workaround as it closes the last activity
before attempting to end each test.
Original comment by jie...@xero.com
on 8 May 2014 at 8:35
I too have seen this quite a bit. Our project currently contains a mix of
Robotium-based tests and Espresso-based tests therefore we have Robotium as a
test dependency in our project. As a hacky workaround for Espresso tests where
this issue reproduces, we use Solo.finishOpenedActivities() from Robotium
during the tearDown() and this resolves the issue for now.
Original comment by mhernan...@gmail.com
on 25 Jun 2014 at 3:26
What does it take to turn the status of this from "New" to "Accepted"?
Original comment by sschuberth
on 26 Jun 2014 at 7:48
[deleted comment]
pressBack solution does not worked for me but I found another:
@Override
protected void tearDown() throws Exception {
closeAllActivities(getInstrumentation());
super.tearDown();
}
public static void closeAllActivities(Instrumentation instrumentation) throws Exception {
final int NUMBER_OF_RETRIES = 100;
int i = 0;
while (closeActivity(instrumentation)) {
if (i++ > NUMBER_OF_RETRIES) {
throw new AssertionError("Limit of retries excesses");
}
Thread.sleep(200);
}
}
public static <X> X callOnMainSync(Instrumentation instrumentation, final Callable<X> callable) throws Exception {
final AtomicReference<X> retAtomic = new AtomicReference<>();
final AtomicReference<Throwable> exceptionAtomic = new AtomicReference<>();
instrumentation.runOnMainSync(new Runnable() {
@Override
public void run() {
try {
retAtomic.set(callable.call());
} catch (Throwable e) {
exceptionAtomic.set(e);
}
}
});
final Throwable exception = exceptionAtomic.get();
if (exception != null) {
Throwables.propagateIfInstanceOf(exception, Exception.class);
Throwables.propagate(exception);
}
return retAtomic.get();
}
public static Set<Activity> getActivitiesInStages(Stage... stages) {
final Set<Activity> activities = Sets.newHashSet();
final ActivityLifecycleMonitor instance = ActivityLifecycleMonitorRegistry.getInstance();
for (Stage stage : stages) {
final Collection<Activity> activitiesInStage = instance.getActivitiesInStage(stage);
if (activitiesInStage != null) {
activities.addAll(activitiesInStage);
}
}
return activities;
}
private static boolean closeActivity(Instrumentation instrumentation) throws Exception {
final Boolean activityClosed = callOnMainSync(instrumentation, new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
final Set<Activity> activities = getActivitiesInStages(Stage.RESUMED,
Stage.STARTED, Stage.PAUSED, Stage.STOPPED, Stage.CREATED);
activities.removeAll(getActivitiesInStages(Stage.DESTROYED));
if (activities.size() > 0) {
final Activity activity = activities.iterator().next();
activity.finish();
return true;
} else {
return false;
}
}
});
if (activityClosed) {
instrumentation.waitForIdleSync();
}
return activityClosed;
}
It works for quite large UI Espresso tests set ~400
(post fixed.. I posted old solution)
Original comment by jacek.ma...@gmail.com
on 31 Jul 2014 at 6:41
Very helpful solution, Jacek. Thanks!
Original comment by wangenhe...@gmail.com
on 15 Oct 2014 at 10:51
Issue 117 has been merged into this issue.
Original comment by nkors...@google.com
on 5 May 2015 at 6:04
Original comment by nkors...@google.com
on 5 May 2015 at 6:05
Original issue reported on code.google.com by
luigimas...@gmail.com
on 10 Apr 2014 at 3:30