Testar as atividades do seu app

As atividades atuam como contêineres para cada interação do usuário no seu app. Por isso, é importante testar o comportamento das atividades durante eventos no dispositivo, como:

  • Outro app, como o de telefone, interrompe a atividade.
  • O sistema destrói e recria sua atividade.
  • O usuário coloca sua atividade em um novo ambiente de janelas, como picture-in-picture (PIP) ou várias janelas.

Em particular, é importante garantir que sua atividade se comporte corretamente em resposta aos eventos descritos em Entenda o ciclo de vida da atividade.

Este guia descreve como avaliar a capacidade do seu app de manter a integridade dos dados e uma boa experiência do usuário à medida que as atividades passam por diferentes estados nos ciclos de vida.

Direcionar o estado de uma atividade

Um aspecto importante do teste das atividades do app envolve colocá-las em estados específicos. Para definir essa parte "determinada" dos testes, use instâncias de ActivityScenario, parte da biblioteca AndroidX Test. Ao usar essa classe, você pode colocar sua atividade em estados que simulam os eventos no nível do dispositivo descritos no início desta página.

ActivityScenario é uma API multiplataforma que pode ser usada em testes de unidade local e em testes de integração no dispositivo. Em um dispositivo real ou virtual, ActivityScenario fornece segurança na linha de execução, sincronizando eventos entre a linha de execução de instrumentação do teste e a linha de execução da atividade em teste. A API também é particularmente adequada para avaliar como uma atividade em teste se comporta quando é destruída ou criada.

Esta seção apresenta os casos de uso mais comuns associados a essa API.

Criar uma atividade

Para criar a atividade em teste, adicione o código mostrado no snippet a seguir:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
        }
    }
    

Depois de criar a atividade, ActivityScenario faz a transição dela para o estado RESUMED. Esse estado indica que sua atividade está sendo executada e está visível para os usuários. Nele, você está livre para interagir com os elementos View da sua atividade usando testes de IU do Espresso.

Como alternativa, você pode usar ActivityScenarioRule para chamar ActivityScenario.launch automaticamente antes de cada teste e ActivityScenario.close na desmontagem do teste. O exemplo abaixo mostra como definir uma regra e ter uma instância de um cenário a partir dela:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @get:Rule var activityScenarioRule = activityScenarioRule<MyActivity>()

        @Test fun testEvent() {
            val scenario = activityScenarioRule.scenario
        }
    }
    

Direcionar a atividade para um novo estado

Para direcionar a atividade para um estado diferente, como CREATED ou STARTED, chame moveToState(). Essa ação simula uma situação em que sua atividade é parada ou pausada, respectivamente, porque é interrompida por outro app ou por uma ação do sistema.

Um exemplo de uso de moveToState() aparece no snippet de código a seguir:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.moveToState(State.CREATED)
        }
    }
    

Determinar o estado atual da atividade

Para determinar o estado atual de uma atividade em teste, verifique o valor do campo state no seu objeto ActivityScenario. É particularmente útil verificar o estado de uma atividade em teste se ela redirecionar para outra atividade ou se encerrar sozinha, como demonstrado no snippet de código a seguir:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              startActivity(Intent(activity, MyOtherActivity::class.java))
            }

            val originalActivityState = scenario.state
        }
    }
    

Recriar a atividade

Se um dispositivo estiver com poucos recursos, o sistema poderá destruir uma atividade, exigindo que o app a recrie quando o usuário voltar para ele. Para simular essas condições, chame recreate():

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.recreate()
        }
    }
    

A classe ActivityScenario mantém o estado da instância salva da atividade e quaisquer objetos anotados usando @NonConfigurationInstance. Esses objetos são carregados na nova instância da atividade em teste.

Recuperar resultados de atividades

Para verificar o código de resultado ou os dados associados a uma atividade concluída, verifique o valor do campo result no seu objeto ActivityScenario, conforme mostrado no snippet de código a seguir:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testResult() {
            val scenario = launchActivity<MyActivity>()
            onView(withId(R.id.finish_button)).perform(click())

            // Activity under test is now finished.

            val resultCode = scenario.result.resultCode
            val resultData = scenario.result.resultData
        }
    }
    

Acionar ações na atividade

Todos os métodos em ActivityScenario são chamadas de bloqueio, então a API exige que você os execute na linha de execução de instrumentação.

Para acionar ações na atividade em teste, use os correspondentes de visualização do Espresso e interaja com os elementos na visualização:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            onView(withId(R.id.refresh)).perform(click())
        }
    }
    

No entanto, caso seja necessário chamar um método na própria atividade, será possível fazê-lo de modo seguro implementando ActivityAction:

    @RunWith(AndroidJUnit4::class)
    class MyTestSuite {
        @Test fun testEvent() {
            val scenario = launchActivity<MyActivity>()
            scenario.onActivity { activity ->
              activity.handleSwipeToRefresh()
            }
        }
    }
    

Para saber mais sobre como a linha de execução funciona em testes do Android, consulte Conceitos básicos de linhas de execução em testes.