Puoi testare la tua app Compose con approcci e pattern consolidati.
Test in isolamento
ComposeTestRule
ti consente di avviare un'attività che mostra qualsiasi elemento componibile:
l'intera applicazione, una singola schermata o un piccolo elemento. È anche una buona
prassi verificare che i composable siano incapsulati correttamente e funzionino
in modo indipendente, consentendo test dell'interfaccia utente più semplici e mirati.
Ciò non significa che devi creare solo test UI delle unità. Anche la definizione dell'ambito dei test dell'interfaccia utente di parti più grandi dell'interfaccia utente è molto importante.
Accedere all'attività e alle risorse dopo aver impostato i propri contenuti
Spesso devi impostare i contenuti in fase di test utilizzando
composeTestRule.setContent
e devi anche accedere alle risorse di attività, ad esempio
per verificare che un testo visualizzato corrisponda a una risorsa stringa. Tuttavia, non puoi chiamare setContent
in una regola creata con createAndroidComposeRule()
se l'attività lo chiama già.
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 abilitarlo, aggiungi questa dipendenza al tuo
modulo:
debugImplementation("androidx.compose.ui:ui-test-manifest:$compose_version")
Proprietà semantiche personalizzate
Puoi creare proprietà semantiche personalizzate per esporre 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 verificare il valore della
proprietà:
composeTestRule
.onNode(SemanticsMatcher.expectValue(PickedDateKey, 1445378400)) // 2015-10-21
.assertExists()
Verificare il ripristino dello stato
Verifica che lo stato degli elementi Compose venga ripristinato correttamente quando l'attività o il processo viene ricreato. Esegui questi controlli senza fare affidamento sulla ricreazione dell'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.
}
}
Testare diverse configurazioni del dispositivo
Le app per Android devono adattarsi a molte condizioni in continua evoluzione: dimensioni delle finestre, impostazioni internazionali,
dimensioni dei caratteri, temi scuri e chiari e altro ancora. La maggior parte di queste condizioni
deriva da valori a livello di dispositivo controllati dall'utente ed esposti con l'istanza
Configuration
corrente. Testare diverse configurazioni
direttamente in un test è difficile, poiché il test deve configurare le proprietà
a livello di dispositivo.
DeviceConfigurationOverride
è un'API solo di test che consente di simulare
diverse configurazioni di dispositivi in modo localizzato per i contenuti @Composable
in fase di test.
L'oggetto complementare 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 per il tema scuro o chiaro.DeviceConfigurationOverride.FontScale()
: esegue l'override della scala del carattere di sistema.DeviceConfigurationOverride.FontWeightAdjustment()
: esegue l'override dell'aggiustamento dello spessore del carattere di sistema.DeviceConfigurationOverride.ForcedSize()
: impone una quantità specifica di spazio indipendentemente 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 delle impostazioni internazionali.DeviceConfigurationOverride.RoundScreen()
: esegue l'override se lo schermo è rotondo.
Per applicare un override specifico, racchiudi i contenuti da testare in una chiamata alla funzione di primo livello
DeviceConfigurationOverride()
, passando l'override
da applicare come parametro.
Ad esempio, il seguente codice applica l'override
DeviceConfigurationOverride.ForcedSize()
per modificare la densità
localmente, forzando il rendering del composable MyScreen
in una finestra
orizzontale di grandi dimensioni, 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
- Testare le app su Android: la pagina di destinazione principale dei test Android offre una visione più ampia dei fondamenti 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 test eseguiti direttamente sul dispositivo.
- Integrazione continua: L'integrazione continua consente di integrare i test nella pipeline di deployment.
- Testa diverse dimensioni dello schermo: con tanti dispositivi a disposizione degli utenti, devi eseguire test per diverse dimensioni dello schermo.
- Espresso: sebbene sia destinato alle UI basate sulla visualizzazione, la conoscenza di Espresso può comunque essere utile per alcuni aspetti dei test di Compose.