Un test locale viene eseguito direttamente sulla tua workstation, anziché su un dispositivo Android dispositivo o emulatore. Pertanto, utilizza la Java Virtual Machine (JVM) locale, anziché su un dispositivo Android. I test locali consentono di valutare della logica dell'app. Tuttavia, la mancata interazione con i Il framework Android crea un limite nei tipi di test che puoi eseguire.
Un test delle unità verifica il comportamento di una piccola sezione di codice, l'unità sotto test. Per farlo, esegue il codice e controlla il risultato.
I test delle unità sono generalmente semplici, ma la loro configurazione può rappresentare un problema quando l'unità di misura sotto test non è progettato in base alla verificabilità:
- Il codice che vuoi verificare deve essere accessibile da un test. Per Ad esempio, non puoi testare direttamente un metodo privato. Devi, invece, testare il corso utilizzando le API pubbliche.
- Per eseguire i test delle unità isolando, le dipendenze dell'unità sottoposti a test devono essere sostituiti con componenti sotto il tuo controllo, come falsi o in un altro doppio di test. Questo è particolarmente problematico se il codice dipende il framework Android.
Per scoprire le strategie più comuni per i test delle unità in Android, leggi l'articolo Cosa test.
Località dei test locali
Per impostazione predefinita, i file di origine per i test delle unità locali vengono inseriti
module-name/src/test/
. Questa directory esiste già quando ne crei una nuova
utilizzando Android Studio.
Aggiunta di dipendenze di test
Devi anche configurare le dipendenze di test per fare in modo che il progetto utilizzi API standard fornite dal framework di test JUnit.
Per farlo, apri il file build.gradle
del modulo dell'app e specifica quanto segue
librerie come dipendenze. Utilizza la funzione testImplementation
per indicare
al set di origini di test locali e non all'applicazione:
dependencies {
// Required -- JUnit 4 framework
testImplementation "junit:junit:$jUnitVersion"
// Optional -- Robolectric environment
testImplementation "androidx.test:core:$androidXTestVersion"
// Optional -- Mockito framework
testImplementation "org.mockito:mockito-core:$mockitoVersion"
// Optional -- mockito-kotlin
testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
// Optional -- Mockk framework
testImplementation "io.mockk:mockk:$mockkVersion"
}
Crea una classe di test delle unità locali
Scrivi la classe di test delle unità locali come classe di test JUnit 4.
Per farlo, crea una classe contenente uno o più metodi di test, di solito in
module-name/src/test/
. Un metodo di test inizia con l'annotazione @Test
e
contiene il codice da esercitare e verificare un singolo aspetto del componente che
che vuoi testare.
L'esempio seguente mostra come implementare una classe di test delle unità locali. La
metodo di test emailValidator_correctEmailSimple_returnsTrue()
tenta di verificare
isValidEmail()
,che è un metodo disponibile all'interno dell'app. La funzione di test restituisce
true seisValidEmail()
restituisce anche true.
Kotlin
import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test class EmailValidatorTest { @Test fun emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")) } }
Java
import org.junit.Test; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; class EmailValidatorTest { @Test public void emailValidator_CorrectEmailSimple_ReturnsTrue() { assertTrue(EmailValidator.isValidEmail("name@email.com")); } }
Devi creare test leggibili per valutare se i componenti nel tuo
restituiscono i risultati previsti. Ti consigliamo di usare una libreria di asserzioni come
come junit.Assert, Hamcrest o
Verità. Lo snippet riportato sopra è un esempio di come utilizzare
junit.Assert
.
Libreria Android simulabile
Quando esegui i test delle unità locali, il plug-in Android per Gradle include una contenente tutte le API del framework Android, corretta nel utilizzata nel progetto. La biblioteca contiene tutti i metodi pubblici e di queste API, ma il codice all'interno dei metodi è stato rimosso. Se presente dei metodi a cui si accede, il test genera un'eccezione.
In questo modo è possibile creare test locali quando si fanno riferimento a classi in Android
come Context
. Ma soprattutto, consente di usare un modello
con le classi di Android.
Simulazione delle dipendenze di Android
Un problema tipico consiste nel scoprire che una classe utilizza una risorsa stringa. Puoi
ottenere risorse stringa richiamando il metodo getString()
nel metodo Context
. Tuttavia, un test locale non può utilizzare Context
o nessuno dei suoi metodi perché
appartengono al framework Android. Idealmente, la chiamata a getString()
sarebbe
hanno abbandonato la classe, ma non è sempre una pratica. La soluzione è
crea una simulazione o uno stub di Context
che restituisca sempre lo stesso valore quando
Metodo getString()
richiamato.
Con la libreria Android simulabile e framework di simulazione come Mockito o MockK, puoi programmare comportamento di simulazioni delle classi Android nei test delle unità.
Per aggiungere un oggetto fittizio al test delle unità locali utilizzando Mockito, segui questo modello di programmazione:
- Includi la dipendenza della libreria Mockito nel file
build.gradle
, ad esempio descritto in Configurare l'ambiente di test. - All'inizio della definizione della classe di test delle unità, aggiungi il metodo
Annotazione
@RunWith(MockitoJUnitRunner.class)
. Questa annotazione indica runner di test simulato per verificare che l'utilizzo del framework sia corretto e semplifica l'inizializzazione degli oggetti fittizi. - Per creare un oggetto fittizio per una dipendenza Android, aggiungi l'annotazione
@Mock
prima della dichiarazione del campo. - Per evitare il comportamento della dipendenza, puoi specificare una condizione
restituisce un valore quando la condizione è soddisfatta utilizzando gli attributi
when()
ethenReturn()
di machine learning.
L'esempio seguente mostra come creare un test delle unità che utilizza una simulazione
Oggetto Context
in Kotlin creato con Mockito-Kotlin.
import android.content.Context
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.junit.MockitoJUnitRunner
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
private const val FAKE_STRING = "HELLO WORLD"
@RunWith(MockitoJUnitRunner::class)
class MockedContextTest {
@Mock
private lateinit var mockContext: Context
@Test
fun readStringFromContext_LocalizedString() {
// Given a mocked Context injected into the object under test...
val mockContext = mock<Context> {
on { getString(R.string.name_label) } doReturn FAKE_STRING
}
val myObjectUnderTest = ClassUnderTest(mockContext)
// ...when the string is returned from the object under test...
val result: String = myObjectUnderTest.getName()
// ...then the result should be the expected one.
assertEquals(result, FAKE_STRING)
}
}
Per scoprire di più sull'utilizzo del framework Mockito, consulta l'articolo sull'API Mockito
riferimento e la classe SharedPreferencesHelperTest
nel
codice campione: Prova anche il codelab di test su Android.
Errore: "Metodo ... non preso in giro"
La libreria Android simulabile genera un'eccezione se tenti di accedere a uno qualsiasi dei suoi
con il messaggio Error: "Method ... not mocked
.
Se le eccezioni generate sono problematiche per i test, puoi modificare il valore
in modo che i metodi restituiscano nullo o zero, a seconda del
tipo restituito. Per farlo, aggiungi la seguente configurazione nel
file build.gradle
di primo livello in Groovy:
android {
...
testOptions {
unitTests.returnDefaultValues = true
}