O café expresso não espera até que a Atividade seja destruída, antes de criar um novo para o próximo teste

A situação

Na documentação oficial aqui:https://google.github.io/android-testing-support-library/docs/rules/index.html, diz:

"Esta regra fornece teste funcional de uma única atividade. A atividade em teste será iniciada antes de cada teste anotado com @Test e antes de qualquer método anotado com @Before.Ele será encerrado após a conclusão do teste e todos os métodos anotados com @After serão concluídos. A atividade em teste pode ser acessada durante o teste chamando ActivityTestRule # getActivity (). "

Tecnicamente sim, a Atividade está sendo encerrada.Mas parece não haver garantia de quando isso acontecerá. Por exemplo. isso não acontecerá necessariamente antes de ser criado novamente para o próximo teste.

O problema

Em alguns dos meus testes, preciso confiar nos fragmentos OnDestroy ou OnDetach que são chamados após cada teste,antes o próximo teste começa. Eu tenho ouvintes que precisam ser limpos e recriados.

Se onDestroy do teste anterior for chamado após OnResume no teste atual, o retorno de chamada será limpo e a visualização não será atualizada e o teste falhará.

Se onDestroy do teste anterior não for chamado, o retorno de chamada do teste atual estará se referindo à instância errada. Novamente, a visualização não será atualizada e o teste falhará.

A questãoEsse comportamento é discutido na situação por design ou é um bug? Até agora, não consigo encontrar isso na documentação.Qual é a melhor prática para lidar com isso? Suspeito que outras pessoas tenham enfrentado esse problema.

Editar: Resolvi agora a parte 2. Consulte a seção de soluções alternativas abaixo. No entanto, se alguém puder responder à parte um citando um recurso oficial, ficarei feliz em aceitar essa resposta. É o que realmente estou perguntando aqui. A segunda parte era apenas um bônus se alguém tivesse algumas idéias.

A prova

Se você gostaria de ver esse comportamento, levará apenas alguns instantes. Crie um novo projeto com uma atividade como esta:

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();
    }
}

e uma classe de teste como esta:

@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() {
    }
}

Coloque pontos de interrupção nos métodos OnResume e OnDestroy e execute o conjunto de testes no modo de depuração.

Faça isso algumas vezes e observe que a ordem em que os métodos do ciclo de vida da atividade são chamados não é consistente. Por exemplo. ele pode chamar OnResume duas vezes seguidas e, em seguida, chamar OnDestroy uma vez, e OnResume duas vezes novamente e, em seguida, OnDestroy três vezes, ou qualquer outra combinação que você possa imaginar. Claro que sempre começa com pelo menos um OnResume. Às vezes, nem chama OnDestroy se estiver no final, mas tudo bem. O que não é bom é que meus testes são difíceis por causa dessa ordem imprevisível.

Estou ciente de que isso pode ser intencional e pode haver uma maneira simples de lidar com isso, mas não tenho a sorte de ter encontrado. Por favor, se você souber o que é, poste a resposta aqui. Eu não me importo com o quão estúpida minha pergunta possa ser, eu passei muito tempo com esse problema. É quase sempre algo simples, por isso estou preparado para ficar envergonhado com a resposta.

Soluções alternativas

O uso de onPause sobre OnDestroy tem o efeito colateral de ser chamado quando eu inicioActivityForResult, mas sem chamar onResume novamente no fragmento de plano de fundo enquanto estiver no modo tablet. Estou explorando maneiras de fazer isso funcionar, mas ainda não há solução.

Editar: O onPause acabou com o mesmo problema - e é em parte por isso que eu estava usando o onDetach. Por fim, há momentos em que não quero desconectar os ouvintes até que o fragmento seja destruído.

Isso me leva à minha próxima idéia que funcionou! Viva! Até agora, eu estava criando um retorno de chamada para a atividade de chamada, para o que estava pedindo, se esse retorno de chamada específico não existisse. Acontece que essa foi uma péssima idéia. Fiz isso para limitar o número de retornos de chamada ao número exato necessário. A motivação foi boa, mas a implementação exigiu toda essa compensação de retorno de chamada. A solução é recriar cada retorno de chamada sempre que for chamado a partir do fragmento. Não o crie se for nulo,sempre crie e substitua o que havia antes. Agora não há necessidade de limpá-las (AFAIK).

questionAnswers(2)

yourAnswerToTheQuestion