Sincronizar seus testes

Por padrão, os testes do Compose são sincronizados com sua IU. Quando você chama ou uma ação com o ComposeTestRule, o teste será sincronizado. antes, aguardando até que a árvore da interface esteja ociosa.

Normalmente, não é necessário fazer nada. No entanto, existem alguns casos extremos que você precisa conhecer.

Quando um teste é sincronizado, o tempo do app Compose é avançado usando um relógio virtual. Isso significa que os testes do Compose não são executados em tempo real, para que possam ser realizados o mais rápido possível.

No entanto, caso você não use os métodos que sincronizam os testes, nenhuma recomposição vai ocorrer, e a IU aparentará estar pausada.

@Test
fun counterTest() {
    val myCounter = mutableStateOf(0) // State that can cause recompositions.
    var lastSeenValue = 0 // Used to track recompositions.
    composeTestRule.setContent {
        Text(myCounter.value.toString())
        lastSeenValue = myCounter.value
    }
    myCounter.value = 1 // The state changes, but there is no recomposition.

    // Fails because nothing triggered a recomposition.
    assertTrue(lastSeenValue == 1)

    // Passes because the assertion triggers recomposition.
    composeTestRule.onNodeWithText("1").assertExists()
}

Esse requisito se aplica apenas às hierarquias do Compose, e não às restante do app.

Desativar a sincronização automática

Quando você chama uma declaração ou ação usando ComposeTestRule, como assertExists(), seu teste é sincronizado com a IU do Compose. Em alguns casos, pode ser necessário interromper essa sincronização e controlar o relógio. Por exemplo, você pode controlar o tempo para fazer capturas de tela precisas de uma animação em um ponto em que a IU ainda estaria ocupada. Para desativar a sincronização automática, defina a propriedade autoAdvance em mainClock como false:

composeTestRule.mainClock.autoAdvance = false

Normalmente, isso fará com que o tempo seja avançado. É possível avançar exatamente um frame com advanceTimeByFrame() ou um intervalo específico com advanceTimeBy():

composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.mainClock.advanceTimeBy(milliseconds)

Recursos inativos

O Compose pode sincronizar testes e a IU para que todas as ações e declarações sejam executadas em estado inativo enquanto estão aguardando ou avançando o relógio conforme necessário. No entanto, algumas operações assíncronas com resultados que afetam o estado da IU podem ser executadas em segundo plano enquanto não afetam os testes.

Crie e registre esses recursos de inatividade no teste para que eles sejam usados. em conta ao decidir se o app em teste está ocupado ou inativo. Você não precisam tomar medidas a menos que você precise registrar recursos de inatividade adicionais, por exemplo, se você executar um trabalho em segundo plano que não seja sincronizado com o Espresso ou Escrever.

Essa API é muito semelhante aos Recursos de inatividade do Espresso, para indicar se o objeto em teste está ocioso ou ocupado. Use a regra de teste do Compose para registrar a implementação do IdlingResource.

composeTestRule.registerIdlingResource(idlingResource)
composeTestRule.unregisterIdlingResource(idlingResource)

Sincronização manual

Em alguns casos, você precisa sincronizar a IU do Compose com outras partes do teste ou do app sendo testado.

A função waitForIdle() espera que o Compose fique inativo, mas a função depende da propriedade autoAdvance:

composeTestRule.mainClock.autoAdvance = true // Default
composeTestRule.waitForIdle() // Advances the clock until Compose is idle.

composeTestRule.mainClock.autoAdvance = false
composeTestRule.waitForIdle() // Only waits for idling resources to become idle.

Em ambos os casos, waitForIdle() também aguarda transmissões de layout e desenho pendentes.

Além disso, você pode avançar o relógio até que uma determinada condição seja atendida com advanceTimeUntil().

composeTestRule.mainClock.advanceTimeUntil(timeoutMs) { condition }

A condição especificada precisa ser verificar o estado que pode ser afetado por esse relógio. Isso só funciona com estados no Compose.

Aguardar condições

Qualquer condição que depende de trabalho externo, como carregamento de dados ou medir ou desenhar (ou seja, medir ou desenhar externamente ao Compose), use uma conceito mais geral, como waitUntil():

composeTestRule.waitUntil(timeoutMs) { condition }

Você também pode usar qualquer um dos Assistentes do waitUntil:

composeTestRule.waitUntilAtLeastOneExists(matcher, timeoutMs)

composeTestRule.waitUntilDoesNotExist(matcher, timeoutMs)

composeTestRule.waitUntilExactlyOneExists(matcher, timeoutMs)

composeTestRule.waitUntilNodeCount(matcher, count, timeoutMs)

Outros recursos

  • Testar apps no Android: os principais testes do Android. página de destino oferece uma visão mais ampla dos fundamentos e das técnicas de teste.
  • Conceitos básicos de testes: saiba mais sobre os principais conceitos por trás dos testes de um app Android.
  • Testes locais: é possível executar alguns testes localmente na sua estação de trabalho.
  • Testes instrumentados:é bom praticar também a execução de testes instrumentados. Ou seja, testes que são executados diretamente no dispositivo.
  • Integração contínua: a integração contínua permite integrar seus testes ao pipeline de implantação.
  • Teste diferentes tamanhos de tela:com alguns dispositivos disponíveis para os usuários, teste diferentes telas tamanhos.
  • Espresso: embora seja destinado a interfaces baseadas em visualizações, o conhecimento do Espresso ainda pode ser útil para alguns aspectos dos testes do Compose.