Questo argomento descrive come includere le API fornite dal framework nei test che valutano il comportamento di ogni frammento.
I frammenti servono come contenitori riutilizzabili all'interno dell'app, consentendoti presentano lo stesso layout dell'interfaccia utente in una serie di attività configurazioni di layout. Data la versatilità dei frammenti, è importante per verificare che forniscano un'esperienza coerente ed efficiente nell'uso delle risorse. Nota:
- Il frammento non deve dipendere da un'attività principale specifica o .
- Non devi creare la gerarchia di visualizzazione di un frammento, a meno che quest'ultimo è visibile all'utente.
Per configurare le condizioni necessarie per l'esecuzione di questi test, AndroidX
La libreria fragment-testing
offre le
FragmentScenario
per creare frammenti e modificarne
Lifecycle.State
.
Dichiarazione delle dipendenze
Per utilizzare FragmentScenario
, definisci l'artefatto fragment-testing-manifest
nel
il file build.gradle
dell'app con debugImplementation
e l'elemento fragment-testing
con androidTestImplementation
, come mostrato in
nell'esempio seguente:
Groovy
dependencies { def fragment_version = "1.8.5" debugImplementation "androidx.fragment:fragment-testing-manifest:$fragment_version" androidTestImplementation "androidx.fragment:fragment-testing:$fragment_version" }
Kotlin
dependencies { val fragment_version = "1.8.5" debugImplementation("androidx.fragment:fragment-testing-manifest:$fragment_version") androidTestImplementation("androidx.fragment:fragment-testing:$fragment_version") }
Gli esempi di test in questa pagina utilizzano le asserzioni del Espresso e librerie Truth. Per informazioni su altre librerie di test e asserzioni disponibili, vedi Configura il progetto per il test AndroidX.
Crea un frammento
FragmentScenario
include i seguenti metodi per avviare i frammenti
nei test:
launchInContainer()
, per testare l'interfaccia utente di un frammento.FragmentScenario
allega al controller della vista principale di un'attività. Contenuti contenenti attività altrimenti è vuoto.launch()
, per i test senza l'interfaccia utente del frammento.FragmentScenario
collega questo tipo di frammento a un'attività vuota, che non avere una vista root.
Dopo aver avviato uno di questi tipi di frammenti, FragmentScenario
guida la
del frammento sottoposto a test in uno stato specificato. Per impostazione predefinita, questo stato è RESUMED
,
ma puoi sostituirlo con l'argomento initialState
. Lo stato RESUMED
indica che il frammento è in esecuzione ed è visibile all'utente. Puoi valutare
informazioni sui suoi elementi UI utilizzando Espresso UI
test.
I seguenti esempi di codice mostrano come avviare il frammento utilizzando ciascun metodo:
Esempio di lancioInContainer()
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" argument is optional.
val fragmentArgs = bundleOf(“selectedListItem” to 0)
val scenario = launchFragmentInContainer<EventFragment>(fragmentArgs)
...
}
}
Esempio di lancio()
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
// The "fragmentArgs" arguments are optional.
val fragmentArgs = bundleOf("numElements" to 0)
val scenario = launchFragment<EventFragment>(fragmentArgs)
...
}
}
Fornisci le dipendenze
Se i tuoi frammenti hanno dipendenze, puoi fornire versioni di test di
queste dipendenze fornendo un valore FragmentFactory
personalizzato
launchInContainer()
o launch()
.
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val someDependency = TestDependency()
launchFragmentInContainer {
EventFragment(someDependency)
}
...
}
}
Per ulteriori informazioni sull'utilizzo di FragmentFactory
per fornire
le dipendenze ai frammenti, vedi
Gestore dei frammenti:
Porta il frammento a un nuovo stato
Nei test dell'interfaccia utente dell'app, di solito è sufficiente lanciare il frammento
in corso e inizia a testarlo da uno stato RESUMED
. In modo più granulare
test delle unità; tuttavia, potresti anche valutare il comportamento del frammento
durante la transizione da uno stato del ciclo di vita a un altro. Puoi specificare
stato iniziale passando l'argomento initialState
a uno qualsiasi degli
Funzioni di launchFragment*()
.
Per portare il frammento a uno stato del ciclo di vita diverso, chiama
moveToState()
Questo metodo supporta i seguenti stati come argomenti: CREATED
,
STARTED
, RESUMED
e DESTROYED
. Questo metodo simula una situazione
dove il frammento o l'attività contenente il frammento ne modifica la
per qualsiasi motivo.
L'esempio seguente avvia un frammento di test nello stato INITIALIZED
e
quindi lo sposta nello stato RESUMED
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>(
initialState = Lifecycle.State.INITIALIZED
)
// EventFragment has gone through onAttach(), but not onCreate().
// Verify the initial state.
scenario.moveToState(Lifecycle.State.RESUMED)
// EventFragment moves to CREATED -> STARTED -> RESUMED.
...
}
}
Ricrea il frammento
Se la tua app è in esecuzione su un dispositivo che sta per esaurire le risorse, il sistema
potrebbe distruggere l'attività contenente il frammento. Questa situazione
richiede che l'app ricrei il frammento quando l'utente vi ritorna.
Per simulare questa situazione, chiama recreate()
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
scenario.recreate()
...
}
}
FragmentScenario.recreate()
distrugge il frammento e il suo host e poi li ricrea. Quando
La classe FragmentScenario
ricrea il frammento sottoposto a test, ovvero
torna allo stato del ciclo di vita precedente all'eliminazione.
Interazione con i frammenti di UI
Per attivare le azioni dell'interfaccia utente nel frammento sottoposto a test, utilizza Corrispondenza visualizzazione espresso per interagire con gli elementi visualizzati:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
onView(withId(R.id.refresh)).perform(click())
// Assert some expected behavior
...
}
}
Se devi chiamare un metodo sul frammento stesso, ad esempio rispondendo
a una selezione nel menu delle opzioni, puoi farlo in sicurezza ottenendo
riferimento al frammento utilizzando
FragmentScenario.onFragment()
e passando attraverso un
FragmentAction
:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testEventFragment() {
val scenario = launchFragmentInContainer<EventFragment>()
scenario.onFragment { fragment ->
fragment.myInstanceMethod()
}
}
}
Azioni della finestra di dialogo di test
FragmentScenario
supporta anche i test
frammenti di dialogo. Anche se i frammenti di dialogo
presentano elementi UI, il loro layout viene inserito in una finestra separata, anziché
piuttosto che nell'attività stessa. Per questo motivo, utilizza
FragmentScenario.launch()
per testare i frammenti di finestra di dialogo.
L'esempio seguente verifica il processo di chiusura delle finestre di dialogo:
@RunWith(AndroidJUnit4::class)
class MyTestSuite {
@Test fun testDismissDialogFragment() {
// Assumes that "MyDialogFragment" extends the DialogFragment class.
with(launchFragment<MyDialogFragment>()) {
onFragment { fragment ->
assertThat(fragment.dialog).isNotNull()
assertThat(fragment.requireDialog().isShowing).isTrue()
fragment.dismiss()
fragment.parentFragmentManager.executePendingTransactions()
assertThat(fragment.dialog).isNull()
}
}
// Assumes that the dialog had a button
// containing the text "Cancel".
onView(withText("Cancel")).check(doesNotExist())
}
}