круто, не могли бы вы поделиться своим решением? :) Думаю, это поможет другим, у кого может быть такая же проблема.

ция

В официальной документации здесь: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).

Ответы на вопрос(2)

Ваш ответ на вопрос