круто, не могли бы вы поделиться своим решением? :) Думаю, это поможет другим, у кого может быть такая же проблема.
В официальной документации здесь:https://google.github.io/android-testing-support-library/docs/rules/index.html, это говорит:
«Это правило обеспечивает функциональное тестирование одного действия. Тестируемое действие будет запускаться перед каждым тестом, аннотированным @Test, и перед любым методом, аннотированным @Before.Он будет завершен после завершения теста и завершения всех методов, помеченных @After., Доступ к тестируемой активности можно получить во время теста, вызвав ActivityTestRule # getActivity (). "
Технически да, Деятельность прекращается.Но, похоже, нет никаких гарантий относительно того, когда это произойдет., Например. это не обязательно произойдет, прежде чем он будет создан снова для следующего теста.
Эта проблемаВ некоторых из моих тестов мне нужно полагаться на фрагменты OnDestroy или OnDetach, вызываемые после каждого теста,до следующий тест начинается. У меня есть слушатели, которых нужно очистить и воссоздать.
Если onDestroy из предыдущего теста вызывается после OnResume в текущем тесте, тогда обратный вызов очищается, и представление не обновляется, и тест завершается неудачей.
Если onDestroy из предыдущего теста вообще не вызывается, то обратный вызов из текущего теста будет ссылаться на неправильный экземпляр. Снова представление не будет обновлено и тест не пройден.
ВопросЭто поведение обсуждается в данной ситуации по замыслу или это ошибка? Я до сих пор не могу найти это в документации.Как лучше всего справляться с этим? Я подозреваю, что другие люди столкнулись с этой проблемой.редактировать: Теперь я решил часть 2. См. Раздел обходных путей ниже. Однако, если кто-то может ответить на первую часть, сославшись на официальный ресурс, я был бы рад принять этот ответ. Это то, что я действительно спрашиваю здесь. Вторая часть была просто бонусом, если у кого-то были какие-то идеи.
ДоказательствоЕсли вы хотите увидеть это поведение, это займет всего несколько минут. Создайте новый проект с деятельностью, подобной этой:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
и тестовый класс, как это:
@RunWith(AndroidJUnit4.class)
@LargeTest
public class EspressoLifecycleTest {
@Rule
public ActivityTestRule<MainActivity> mActivityRule =
new ActivityTestRule<>(MainActivity.class);
@Test
public void test1() {
}
@Test
public void test2() {
}
@Test
public void test3() {
}
@Test
public void test4() {
}
}
Установите точки останова для методов OnResume и OnDestroy и запустите набор тестов в режиме отладки.
Сделайте это несколько раз и обратите внимание, что порядок вызова методов жизненного цикла Activity не согласован. Например. он может вызывать OnResume дважды подряд, а затем вызывать OnDestroy один раз, затем OnResume дважды снова, а затем OnDestroy три раза, или любую другую комбинацию, о которой вы только можете подумать. Конечно, он всегда начинается хотя бы с одного OnResume. Иногда он даже не вызывает OnDestroy, если он в самом конце, но это нормально. Что не хорошо, так это то, что мои тесты не очень удачные из-за этого непредсказуемого порядка.
Я знаю, что это может быть преднамеренным и может быть простой способ справиться с этим, мне просто не повезло найти его. Пожалуйста, если вы знаете, что это, отправьте ответ здесь. Мне все равно, насколько глупым может быть мой вопрос задним числом, я потратил много времени на эту проблему. Это почти всегда что-то простое, поэтому я готов быть смущен ответом.
обходныеИспользование onPause поверх OnDestroy имеет побочный эффект при вызове, когда я запускаюActivityForResult, но без повторного вызова onResume во фрагменте фона в режиме планшета. Я изучаю способы сделать эту работу, но пока нет решения.
Редактировать: У onPause возникла та же проблема - отчасти поэтому я и использовал onDetach. В конечном счете, бывают случаи, когда я не хочу отсоединять слушателей, пока фрагмент не будет уничтожен.
Это приводит меня к моей следующей идее, которая сработала! Ура! До сих пор я создавал обратный вызов для вызывающего Activity, для того, о чем он просил,только если этот конкретный обратный вызов не существует. Оказывается, это была плохая идея. Я сделал это, чтобы ограничить количество обратных вызовов точным количеством. Мотивация была здравой, но реализация требовала всей этой очистки обратного вызова. Решение состоит в том, чтобы воссоздать каждый обратный вызов, когда бы он ни вызывался из фрагмента. Не создавайте его, если он нулевой,всегда создать его и заменить то, что было раньше. Теперь их вообще не нужно очищать (AFAIK).