Robolectric è un framework per test unitari di applicazioni Android che consente di eseguire test direttamente sulla JVM senza emulatore o dispositivo fisico. Intercetta le chiamate dell'Android SDK e fornisce shadow-object che emulano il comportamento dei componenti reali. Secondo Robolectric Documentation, 2025, gli shadow-object sostituiscono circa 15 mila classi dell'API Android, garantendo l'isolamento dei test dalla piattaforma.
Punti chiave
Robolectric è un framework open source creato nel 2010 per accelerare i test delle applicazioni Android. Invece di eseguire su un emulatore o dispositivo, Robolectric fornisce implementazioni shadow delle classi dell'Android SDK che funzionano direttamente sulla Macchina Virtuale Java (JVM). Ciò consente di eseguire migliaia di test in pochi secondi.
Il test Android tradizionale richiede l'esecuzione dell'applicazione su un emulatore, che richiede 3–10 minuti per compilare l'APK, installarlo e avviarlo. Robolectric elimina questo passaggio: i test vengono compilati come normali test Java/Kotlin ed eseguiti tramite JUnit. Questo fornisce un ciclo di feedback di secondi invece di minuti.
Robolectric supporta tutte le versioni Android dall'API 16 (Android 4.1) fino all'ultima versione stabile. Per ogni versione viene fornito un corrispondente set di shadow-object che emulano il comportamento della versione specifica della piattaforma su cui l'applicazione viene testata.
L'architettura di Robolectric si basa sul meccanismo di intercettazione delle chiamate tramite sostituzione del classloader. Quando un test chiama un metodo dell'Android SDK, Robolectric intercetta la chiamata e la indirizza a uno shadow-object. Uno shadow-object è una classe Java che imita il comportamento reale di un componente Android ma funziona senza la piattaforma nativa.
Gli shadow-object implementano i metodi chiave delle classi Android originali. Ad esempio, ShadowTextView imita metodi come getText(), setText(), getCurrentTextColor() e altri. Quando viene chiamato textView.setText("Ciao"), lo shadow salva la stringa e la restituisce quando viene invocato getText(). Questo isola i test dal rendering reale e dai servizi di sistema.
Robolectric supporta oltre 200 classi shadow che coprono i principali componenti dell'Android SDK: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager e molti altri. Gli shadow-object seguono la stessa gerarchia di ereditarietà delle classi Android originali.
L'installazione di Robolectric in un progetto Gradle richiede l'aggiunta della dipendenza testImplementation "org.robolectric:robolectric:4.x". È inoltre necessario specificare la configurazione androidsdk nel file build.gradle e aggiungere la risoluzione android:testInstrumentationRunner. Non è richiesto alcun plugin di test Android per lavorare con Robolectric.
Dopo aver aggiunto la dipendenza, è necessario configurare la directory per il manifest, le risorse e gli asset. Robolectric trova automaticamente AndroidManifest.xml, ma potrebbe essere necessario specificare il percorso manualmente tramite l'annotazione @Config o le proprietà di sistema. Per i progetti multimodulo, la configurazione viene impostata separatamente per ciascun modulo.
// build.gradle — configurazione di Robolectric
android {
testOptions {
unitTests.includeAndroidResources = true
unitTests.all {
systemProperty 'robolectric.dependency.dir',
project.rootDir.absolutePath + '/build/intermediates'
}
}
}
dependencies {
testImplementation 'org.robolectric:robolectric:4.13'
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
L'annotazione @Config consente di sovrascrivere i parametri del test: sdk (versione API), manifest (percorso del manifest), qualifiers (configurazione schermo, lingua). Ciò è utile per testare il comportamento dell'applicazione su diverse versioni Android, orientamenti dello schermo e localizzazioni.
I test Robolectric sono scritti come normali test unitari con @RunWith(RobolectricTestRunner.class) per JUnit 4 o tramite RobolectricExtension per JUnit 5. ActivityController gestisce il ciclo di vita dell'Activity: create(), start(), resume(), pause(), stop(), destroy(). Ciò consente di testare in dettaglio ogni transizione di stato.
Per testare un'Activity si utilizza ActivityController, che attraversa sequenzialmente le fasi del ciclo di vita. L'accesso all'Activity avviene tramite controller.get(). Tutti i componenti della vista sono accessibili tramite findViewById, come in un'applicazione reale. Gli shadow-object consentono di verificare testi, visibilità, colori e altri attributi delle viste.
@RunWith(RobolectricTestRunner.class)
@Config(sdk = BuildConfig.SDK_INT)
public class MainActivityTest {
@Test
public void testActivityDisplaysGreeting() {
ActivityController<MainActivity> controller =
Robolectric.buildActivity(MainActivity.class);
controller.create().start().resume();
MainActivity activity = controller.get();
TextView greeting = activity.findViewById(R.id.greeting);
ShadowTextView shadow = Shadows.shadowOf(greeting);
assertEquals("Welcome!", shadow.getText());
}
}
Robolectric intercetta le chiamate startActivity() e consente di verificare gli intent inviati tramite ShadowActivity. Ciò permette di testare la navigazione: verificare che cliccando un pulsante venga inviato un Intent con i corretti parametri Action, Data ed Extra.
@Test
public void testNavigationToDetails() {
controller.create().start().resume();
MainActivity activity = controller.get();
activity.findViewById(R.id.detailsButton).performClick();
ShadowActivity shadowActivity = Shadows.shadowOf(activity);
Intent intent = shadowActivity.getNextStartedActivity();
assertEquals(
DetailsActivity.class.getName(),
intent.getComponent().getClassName()
);
}
Robolectric e l'emulatore risolvono compiti diversi. Robolectric è ideale per test unitari rapidi, verifica della logica dell'interfaccia utente, componenti aziendali e repository. L'emulatore è necessario per i test di strumentazione, verifica dell'integrazione con le API, test della fotocamera, sensori e prestazioni.
| Caratteristica | Robolectric | Emulatore |
|---|---|---|
| Velocità | ~5 sec per 100 test | ~5 min per 100 test |
| Avvio | Senza compilazione APK | Richiede compilazione APK |
| API reale | Shadow-emulazione | Android SDK nativo |
| Pronto all'uso | Solo JUnit | Qualsiasi framework |
Robolectric è eccellente per testare ViewModel, Repository e UseCase — componenti che utilizzano l'Android SDK ma non richiedono un'interfaccia utente reale. Il ViewModel viene testato tramite un normale test JUnit con RobolectricExtension, mentre i componenti del ciclo di vita (LiveData, StateFlow) funzionano nell'ambiente shadow senza mock.
Robolectric supporta LiveData direttamente: puoi iscriverti a LiveData nel test, modificare lo stato tramite ViewModel e verificare il valore emesso. Per le operazioni asincrone si utilizza InstantTaskExecutorRule o runBlocking per le coroutine. Ciò elimina la necessità di simulare i componenti architetturali.
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [BuildConfig.SDK_INT])
class ProfileViewModelTest {
private val repository = FakeUserRepository()
private val viewModel = ProfileViewModel(repository)
@Test
fun `loading profile sets state to success`() = runBlocking {
viewModel.loadProfile("user123")
val state = viewModel.profileState.getOrAwaitValue()
Assertions.assertTrue(state is UiState.Success)
}
}
Se gli shadow-object standard di Robolectric non coprono una classe necessaria dell'Android SDK, puoi creare uno Shadow personalizzato. Per farlo, crea una classe con l'annotazione @Implements(ClassName.class) e implementa i metodi necessari con @Implementation. Gli shadow personalizzati vengono registrati tramite @Config(shadows = [CustomShadow::class]).
Robolectric supporta il test di ContentProvider tramite Robolectric.buildContentProvider(). Puoi verificare le operazioni CRUD, le query con corrispondenza URI e la gestione dei permessi di accesso. Le risorse (stringhe, colori, dimensioni) sono accessibili anche tramite RuntimeEnvironment.application.resources, consentendo di testare il codice che dipende dalle risorse.
La transizione dai test di strumentazione a Robolectric richiede un cambiamento di approccio. I test di strumentazione (AndroidJUnit4) verificano il comportamento reale sull'emulatore, mentre Robolectric verifica la logica isolata in un ambiente shadow. Si consiglia di coprire la logica aziendale con test Robolectric e lasciare i test di strumentazione per scenari di integrazione.
Durante la migrazione, è necessario: sostituire AndroidJUnit4 con RobolectricTestRunner, aggiungere @Config con la versione SDK target, sostituire ActivityTestRule con ActivityController e spostare le dipendenze da androidTestImplementation a testImplementation. I mock (MockK, Mockito) funzionano con Robolectric senza modifiche — sono indipendenti dalla piattaforma.
Robolectric non supporta: test della fotocamera (CameraX), NFC, Bluetooth, biometria, lavoro con file reali e librerie native. Questi scenari richiedono test di strumentazione sull'emulatore. Robolectric inoltre non riproduce il rendering reale — i test di layout sono migliori tramite Compose Test Rule o Espresso. Tuttavia, per verificare la logica aziendale, la navigazione e gli stati del ViewModel, Robolectric sostituisce completamente l'emulatore con un'accelerazione di 10x.
Robolectric richiede JDK 11 o superiore ed è compatibile con AGP (Android Gradle Plugin) da 7.0 all'ultima versione stabile. Il SDK Manager di Robolectric scarica automaticamente le versioni API Android necessarie al primo avvio — è un'operazione una tantum. Per i server CI, si consiglia di precaricare l'SDK tramite sdkmanager per evitare ritardi al primo esecuzione dei test. L'aggiornamento di Robolectric a una nuova versione di solito non richiede modifiche al codice dei test, solo l'aggiornamento del numero di dipendenza in build.gradle.
Robolectric è compatibile con i popolari framework di mocking: MockK per Kotlin e Mockito per Java. I mock vengono utilizzati per isolare le dipendenze: repository, client API, SharedPreferences. La regola principale è non simulare le classi dell'Android SDK — per questo esistono gli shadow-object. Simula solo i livelli applicativi: UseCase, Repository, DataSource e altri componenti della logica aziendale. Questa combinazione di shadow-object e mock offre la massima flessibilità con il minimo sforzo di scrittura dei test.
Domande frequenti
Espresso è un framework di strumentazione che viene eseguito su un emulatore o dispositivo. Robolectric è un framework di test unitari che funziona sulla JVM. Espresso testa il comportamento reale, Robolectric testa la logica isolata in un ambiente shadow. Si completano a vicenda.
Sì, Robolectric supporta Jetpack Compose a partire dalla versione 4.8. I test dei componenti Compose vengono eseguiti con ComposeTestRule, in modo simile all'emulatore. Tuttavia, i test Compose su Robolectric non verificano il rendering reale — solo la logica di composizione.
Robolectric supporta progetti multimodulo. Ogni modulo viene configurato separatamente con il proprio manifest e le proprie risorse. Per i moduli senza componenti dell'interfaccia utente, è sufficiente un modulo libreria senza plugin Android. Nei grandi progetti con decine di moduli, i test Robolectric di ciascun modulo vengono eseguiti in parallelo, offrendo un ulteriore vantaggio in velocità rispetto all'esecuzione sequenziale sull'emulatore.
Il problema delle risorse si verifica se nel build.gradle non è presente unitTests.includeAndroidResources = true o manca l'annotazione @Config con il percorso corretto del manifest. Robolectric utilizza le risorse compilate da build/intermediates.
I test Robolectric vengono sottoposti a debug come normali test Java/Kotlin in Android Studio. Punti di interruzione, debug passo-passo e ispezione degli shadow-object e del loro stato sono disponibili. La registrazione viene attivata tramite -Drobolectric.logging=debug nelle opzioni della VM.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche