Puoi testare l'app Compose con approcci e pattern consolidati.
Test in isolamento
ComposeTestRule
consente di iniziare un'attività visualizzando qualsiasi componibile:
l'applicazione completa, una singola schermata o un piccolo elemento. Inoltre, è buona norma verificare che i componibili siano incapsulati correttamente e che funzionino in modo indipendente, consentendo test dell'interfaccia utente più semplici e mirati.
Questo non significa che devi creare solo test dell'interfaccia utente delle unità. Sono molto importanti anche i test che mirano a parti più ampie dell'interfaccia utente.
Accedi all'attività e alle risorse dopo aver impostato i tuoi contenuti
Spesso è necessario impostare il contenuto in fase di test utilizzando composeTestRule.setContent
e anche accedere alle risorse di attività, ad esempio per affermare che un testo visualizzato corrisponde a una risorsa stringa. Tuttavia, non puoi chiamare setContent
per una regola creata con createAndroidComposeRule()
se
l'attività la chiama già.
Un pattern comune per raggiungere questo obiettivo è 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
dell'app. Abilitala aggiungendo questa dipendenza al modulo:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
Proprietà della 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 quella proprietà nel modificatore semantics
:
val datePickerValue by remember { mutableStateOf(0L) }
MyCustomDatePicker(
modifier = Modifier.semantics { pickedDate = datePickerValue }
)
Nei test, utilizza SemanticsMatcher.expectValue
per rivendicare il valore della
proprietà:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
Verifica il ripristino dello stato
Verifica che lo stato degli elementi Compose venga ripristinato correttamente quando
l'attività o il processo vengono ricreati. Esegui questi controlli senza fare affidamento sulla ricreazione delle attività con la classe StateRestorationTester
.
Questa classe consente di simulare la ricreazione di un componibile. È particolarmente utile 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.
}
}
Prova diverse configurazioni del dispositivo
Le app per Android devono adattarsi a molte condizioni variabili: dimensioni delle finestre, impostazioni internazionali, dimensioni dei caratteri, temi chiari e scuri e altro ancora. La maggior parte di queste condizioni
deriva dai valori a livello di dispositivo controllati dall'utente ed esposta con
l'istanza Configuration
corrente. Testare diverse configurazioni
direttamente in un test è difficile poiché il test deve configurare proprietà
a livello di dispositivo.
DeviceConfigurationOverride
è un'API di solo test che ti consente di simulare configurazioni di dispositivi diverse in modo localizzato per i contenuti @Composable
in fase di test.
L'oggetto associato di DeviceConfigurationOverride
ha le seguenti
funzioni di estensione, che sostituiscono le proprietà di configurazione a livello di dispositivo:
DeviceConfigurationOverride.DarkMode()
: esegue l'override del sistema su tema scuro o tema chiaro.DeviceConfigurationOverride.FontScale()
: esegue l'override della scalabilità dei caratteri di sistema.DeviceConfigurationOverride.FontWeightAdjustment()
: sostituisce la regolazione dello spessore del carattere di sistema.DeviceConfigurationOverride.ForcedSize()
: forza una quantità specifica di spazio a prescindere dalle dimensioni del dispositivo.DeviceConfigurationOverride.LayoutDirection()
: esegue l'override della direzione del layout (da sinistra a destra o da destra a sinistra).DeviceConfigurationOverride.Locales()
: esegue l'override della lingua locale.DeviceConfigurationOverride.RoundScreen()
: esegue l'override se lo schermo è rotondo.
Per applicare un override specifico, aggrega i contenuti sottoposti a test in una chiamata alla funzione di primo livello di DeviceConfigurationOverride()
, passando l'override da applicare come parametro.
Ad esempio, il seguente codice applica l'override di DeviceConfigurationOverride.ForcedSize()
per modificare la densità a livello locale, forzando il rendering del componibile MyScreen
in un'ampia finestra orizzontale, anche se il dispositivo su cui viene eseguito il test non supporta direttamente le 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ù override insieme, utilizza
DeviceConfigurationOverride.then()
:
composeTestRule.setContent { DeviceConfigurationOverride( DeviceConfigurationOverride.FontScale(1.5f) then DeviceConfigurationOverride.FontWeightAdjustment(200) ) { Text(text = "text with increased scale and weight") } }
Risorse aggiuntive
- App di test su Android: la pagina di destinazione principale per i test di Android offre una visione più ampia sulle tecniche e sui concetti fondamentali dei 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 in locale, sulla tua workstation.
- Test strumentati: è buona norma eseguire anche test con strumentazione. ovvero test eseguiti direttamente sul dispositivo.
- Integrazione continua: l'integrazione continua consente di integrare i test nella pipeline di deployment.
- Prova dimensioni dello schermo diverse: dato che sono disponibili molti dispositivi per gli utenti, dovresti testare schermi di dimensioni diverse.
- Espresso: sebbene destinato alle UI basate su View, la conoscenza di Espresso può comunque essere utile per alcuni aspetti dei test di Compose.