我有一堆端到端仪器测试(依赖于 Espresso),它们启动我们的启动器活动,然后在我们的应用程序中导航(最终创建多个活动)。在......的最后each测试我们的@After
带注释的拆卸方法执行一些清理工作。
我们遇到的问题是,测试完成(成功或失败的断言)后,应用程序仍在“运行”,因此某些清理实际上导致应用程序崩溃。如果断言成功,这会导致误报,或者隐藏测试失败(我们只看到崩溃而不是失败的断言)。
这是一个例子:
import android.app.Instrumentation;
import android.content.Intent;
import android.preference.PreferenceManager;
import android.support.test.InstrumentationRegistry;
import android.support.test.rule.ActivityTestRule;
import com.example.SplashActivity;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static android.support.test.InstrumentationRegistry.getInstrumentation;
public class ExampleTest {
@Rule
public ActivityTestRule<SplashActivity> splashActivityTestRule
= new ActivityTestRule<>(SplashActivity.class, true, false);
Instrumentation.ActivityMonitor splashActivityMonitor;
@Before
public void setUp() {
splashActivityMonitor = new Instrumentation.ActivityMonitor(SplashActivity.class.getName(), null, false);
getInstrumentation().addMonitor(splashActivityMonitor);
}
@Test
public void someTest() throws Exception {
// ... other test-specific setup before starting splash activity
// start first activity
splashActivityTestRule.launchActivity(new Intent());
// a bunch of espresso steps that result in several other activities
// ... creating and adding Instrumentation.ActivityMonitor for each one
// assert something
}
@After
public void tearDown() {
// clear shared prefs to prepare for next test
PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext())
.edit()
.clear()
.apply();
// At this point the app is still running. Maybe a UI is still loading that was not relevant to the test,
// or some mock web request is in flight. But at some point after the final assert in our test, the app needs
// to get something from shared prefs, which we just cleared, so the app crashes.
}
}
如您所见,应用程序在拆卸方法期间仍在运行。我们在此处对应用程序状态所做的任何更改都可能导致应用程序崩溃。
那么我怎样才能断言该应用程序已经死了并且消失了before做这个清理工作吗?
我想出了一些可能的(但丑陋的)解决方案:
最终断言后,继续导航回应用程序中的某个中立点(即使用 espresso 注销并返回启动屏幕)。这应该可行,但会添加很多其他步骤every测试。另外,我不确定如果断言失败这是否会起作用。
或者在拆卸中执行某种应用程序终止:
public void tearDown() {
// finish all tasks before cleaning up
ActivityManager activityManager =
(ActivityManager) InstrumentationRegistry.getTargetContext().getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.AppTask> appTasks = activityManager.getAppTasks();
for (ActivityManager.AppTask appTask : appTasks) {
appTask.finishAndRemoveTask();
}
// clear shared prefs to prepare for next test
PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext())
.edit()
.clear()
.apply();
}
Update:
我知道我可以使用ActivityTestRule.afterActivityFinished()
docs https://developer.android.com/reference/android/support/test/rule/ActivityTestRule#afterActivityFinished()但我认为这不会起作用multiple活动。