У меня есть несколько комплексных инструментальных тестов (основанных на Espresso), которые запускают нашу деятельность по запуску, а затем перемещаются по нашему приложению (в конечном итоге создавая несколько действий). В конце каждого теста наш @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.
}
}
Как вы можете видеть, приложение все еще работает во время метода сноса. Любые изменения, которые мы вносим в состояние приложения, могут привести к сбою приложения.
Так как я могу утверждать, что приложение мертво и ушло до того, как выполнит эту очистку?
Некоторые возможные (но ужасные) решения, которые я придумала:
После окончательного подтверждения продолжайте возвращаться к некоторой нейтральной точке в приложении (т.е. используйте эспрессо для выхода из системы и возврата к экрану заставки). Это должно работать, но это добавит много других шагов к каждому тесту. Также я не уверен, что это сработает, если не получится подтверждение.
Или выполнить какое-то уничтожение приложения в демонтаже:
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();
}
Обновление:
Я знаю, что могу использовать ActivityTestRule.afterActivityFinished()
документы , но я не думаю, что это будет работать для множественных действий.