As atividades servem como contêineres para cada interação do usuário no seu app. Por isso, é importante testar como as atividades do app se comportam 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 de várias janelas.
Especificamente, é importante garantir que a atividade se comporte corretamente em resposta aos eventos descritos em Ciclo de vida da atividade.
Este guia descreve como avaliar a capacidade do app de manter a integridade dos dados e uma boa experiência do usuário à medida que as atividades fazem a transição por diferentes estados do ciclo de vida.
Direcionar o estado de uma atividade
Um aspecto fundamental dos testes de 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. Com essa classe, você pode
colocar a atividade em estados que simulam eventos no nível do dispositivo.
A ActivityScenario
é uma API multiplataforma que pode ser usada em testes de unidade locais
e de integração no dispositivo. Em um dispositivo real ou virtual,
ActivityScenario
fornece segurança de linha de execução, sincronizando eventos entre a
linha de execução de instrumentação do teste e a linha que executa sua atividade em teste.
A API é 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() { launchActivity<MyActivity>().use { } } }
Depois de criar a atividade, o ActivityScenario
faz a transição dela para o
estado RESUMED
. Esse estado indica que a atividade está em execução e está
visível para os usuários. Nesse estado, você pode interagir com os elementos
View
da atividade usando os testes de interface do Espresso.
O Google recomenda que você chame close
na atividade quando o teste
for concluído. Isso limpa os recursos associados e melhora a
estabilidade dos testes. O ActivityScenario
implementa o Closeable
, para que você possa
aplicar a extensão use
ou try-with-resources
na linguagem de programação
Java, para que a atividade seja fechada automaticamente.
Como alternativa, é possível usar ActivityScenarioRule
para chamar
ActivityScenario.launch
automaticamente antes de cada teste e ActivityScenario.close
na desmontagem do teste. O exemplo a seguir mostra como definir uma regra e receber uma
instância de um cenário 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 a atividade é
interrompida 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() { launchActivity<MyActivity>().use { scenario -> scenario.moveToState(State.CREATED) } } }
Determinar o estado atual da atividade
Para determinar o estado atual de uma atividade em teste, acesse o valor do campo
state
no objeto ActivityScenario
. É particularmente útil
verificar o estado de uma atividade em teste se ela redirecionar para
outra atividade ou se for concluída, conforme demonstrado no snippet de
código abaixo:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> startActivity(Intent(activity, MyOtherActivity::class.java)) } val originalActivityState = scenario.state } } }
Recriar a atividade
Quando um dispositivo está com poucos recursos, o sistema pode destruir uma atividade,
exigindo que o app a recrie quando o usuário retornar.
Para simular essas condições, chame recreate()
:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.recreate() } } }
A classe ActivityScenario
mantém o estado da instância salva da atividade e
todos os objetos anotados usando @NonConfigurationInstance
. Esses objetos são carregados
na nova instância da atividade em teste.
Recuperar resultados de atividades
Para receber o código de resultado ou os dados associados a uma atividade concluída, acesse o
valor do campo result
no objeto ActivityScenario
, conforme mostrado no
snippet de código abaixo:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testResult() { launchActivity<MyActivity>().use { 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. Portanto, 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 para interagir com elementos na sua visualização:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { onView(withId(R.id.refresh)).perform(click()) } } }
No entanto, se você precisar chamar um método na própria atividade, poderá fazer isso
com segurança implementando ActivityAction
:
@RunWith(AndroidJUnit4::class) class MyTestSuite { @Test fun testEvent() { launchActivity<MyActivity>().use { scenario -> scenario.onActivity { activity -> activity.handleSwipeToRefresh() } } } }