Puoi testare la tua app Compose con approcci e pattern consolidati.
Esegui il test in isolamento
ComposeTestRule
ti consente di avviare un'attività che mostra qualsiasi composable:
la tua applicazione completa, una singola schermata o un piccolo elemento. È inoltre buona prassi verificare che i composabili siano incapsulati correttamente e funzionino in modo indipendente, in modo da semplificare e focalizzare i test dell'interfaccia utente.
Ciò non significa che devi creare solo test della UI delle unità. Sono molto importanti anche i test dell'interfaccia utente che prendono l'ambito di parti più grandi dell'interfaccia utente.
Accedere all'attività e alle risorse dopo aver impostato i tuoi contenuti
Spesso devi impostare i contenuti sottoposti a test utilizzando
composeTestRule.setContent
e devi anche accedere alle risorse dell'attività, ad esempio per verificare che un testo visualizzato corrisponda a una risorsa stringa. Tuttavia, non puoi chiamare setContent
in una regola creata con setContent
se l'attività la chiama già.createAndroidComposeRule()
Un pattern comune per ottenere questo risultato è creare un AndroidComposeTestRule
utilizzando
un'attività vuota come ComponentActivity
.
class MyComposeTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun myTest() {
// Start the app
composeTestRule.setContent {
MyAppTheme {
MainScreen(uiState = exampleUiState, /*...*/)
}
}
val continueLabel = composeTestRule.activity.getString(R.string.next)
composeTestRule.onNodeWithText(continueLabel).performClick()
}
}
Tieni presente che ComponentActivity
deve essere aggiunto al file AndroidManifest.xml
della tua app. Per attivarla, aggiungi questa dipendenza al
modulo:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
Proprietà di semantica personalizzata
Puoi creare proprietà semantiche personalizzate per esporre le informazioni ai test.
Per farlo, definisci un nuovo SemanticsPropertyKey
e rendilo disponibile utilizzando
SemanticsPropertyReceiver
.
// Creates a semantics property of type Long.
val PickedDateKey = SemanticsPropertyKey<Long>("PickedDate")
var SemanticsPropertyReceiver.pickedDate by PickedDateKey
Ora utilizza questa proprietà nel modificatore semantics
:
val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
modifier = Modifier.semantics { pickedDate = datePickerValue }
)
Dai test, utilizza SemanticsMatcher.expectValue
per affermare il valore della proprietà:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
Verifica ripristino stato
Verifica che lo stato degli elementi di composizione venga ripristinato correttamente quando l'attività o il processo viene ricreato. Esegui questi controlli senza fare affidamento sulla ricostruzione delle attività con la classe StateRestorationTester
.
Questa classe consente di simulare la ricreazione di un composable. È particolarmente utile per verificare l'implementazione di rememberSaveable
.
class MyStateRestorationTests {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun onRecreation_stateIsRestored() {
val restorationTester = StateRestorationTester(composeTestRule)
restorationTester.setContent { MainScreen() }
// TODO: Run actions that modify the state
// Trigger a recreation
restorationTester.emulateSavedInstanceStateRestore()
// TODO: Verify that state has been correctly restored.
}
}
Testa diverse configurazioni del dispositivo
Le app Android devono adattarsi a molte condizioni mutevoli: dimensioni delle finestre, impostazioni internazionali,
dimensioni dei caratteri, temi chiari e scuri e altro ancora. La maggior parte di queste condizioni è ricavata da valori a livello di dispositivo controllati dall'utente ed esposti con l'istanza Configuration
corrente. Testare configurazioni diverse direttamente in un test è difficile perché il test deve configurare le proprietà a livello di dispositivo.
DeviceConfigurationOverride
è un'API solo per test che consente di simulare diverse configurazioni dei dispositivi in modo localizzato per i contenuti @Composable
sottoposti a test.
L'oggetto complementare di DeviceConfigurationOverride
ha le seguenti funzioni di estensione, che sostituiscono le proprietà di configurazione a livello di dispositivo:
DeviceConfigurationOverride.DarkMode()
: sostituisce il tema scuro o chiaro del sistema.DeviceConfigurationOverride.FontScale()
: sostituisce la scala dei caratteri del sistema.DeviceConfigurationOverride.FontWeightAdjustment()
: sostituisce l'aggiustamento dello spessore dei caratteri di sistema.DeviceConfigurationOverride.ForcedSize()
: forza una quantità specifica di spazio a prescindere dalle dimensioni del dispositivo.DeviceConfigurationOverride.LayoutDirection()
: sostituisce layout direction (da sinistra a destra o da destra a sinistra).DeviceConfigurationOverride.Locales()
: sostituisce la lingua.DeviceConfigurationOverride.RoundScreen()
: esegue l'override se lo schermo è rotondo.
Per applicare una sostituzione specifica, racchiudi i contenuti sottoposti a test in una chiamata alla funzione di primo livello DeviceConfigurationOverride()
, passando la sostituzione da applicare come parametro.
Ad esempio, il codice seguente applica l'override DeviceConfigurationOverride.ForcedSize()
per modificare la densità localmente, forzando il rendering del composable MyScreen
in una finestra ampia in formato orizzontale, anche se il dispositivo su cui viene eseguito il test non supporta direttamente queste dimensioni della finestra:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.ForcedSize(DpSize(1280.dp, 800.dp)) ) { MyScreen() // Will be rendered in the space for 1280dp by 800dp without clipping. } }
Per applicare più sostituzioni contemporaneamente, utilizza
DeviceConfigurationOverride.then()
:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.FontScale(1.5f) then DeviceConfigurationOverride.FontWeightAdjustment(200) ) { Text(text = "text with increased scale and weight") } }
Risorse aggiuntive
- Testare le app su Android: la pagina di destinazione principale per i test su Android offre una visione più ampia delle nozioni di base e delle tecniche di test.
- Nozioni di base sui test: scopri di più sui concetti fondamentali alla base del test di un'app per Android.
- Test locali: puoi eseguire alcuni test localmente, sulla tua workstation.
- Test strumentati: è buona norma eseguire anche test strumentati. ovvero i test eseguiti direttamente sul dispositivo.
- Integrazione continua: l'integrazione continua ti consente di integrare i test nella pipeline di deployment.
- Esegui test su diverse dimensioni dello schermo: con così tanti dispositivi a disposizione degli utenti, devi testare diverse dimensioni dello schermo.
- Espresso: sebbene sia destinato alle UI basate su visualizzazioni, le conoscenze di Espresso possono essere utili per alcuni aspetti dei test di Compose.