Robolectric este un framework pentru testarea unitară a aplicațiilor Android care permite rularea testelor direct pe JVM fără emulator sau dispozitiv fizic. Interceptează apelurile Android SDK și oferă obiecte shadow care emulează comportamentul componentelor reale. Conform Robolectric Documentation, 2025, obiectele shadow înlocuiesc aproximativ 15 mii de clase Android API, asigurând izolarea testelor de platformă.
Principalele puncte
Robolectric este un framework open-source, creat în 2010 pentru accelerarea testării aplicațiilor Android. În loc să ruleze pe emulator sau dispozitiv, Robolectric oferă implementări shadow ale claselor Android SDK care funcționează direct pe Mașina Virtuală Java (JVM). Acest lucru permite executarea a mii de teste în secunde.
Testarea tradițională Android necesită rularea aplicației pe un emulator, ceea ce durează 3–10 minute pentru construirea APK, instalare și pornire. Robolectric elimină acest pas: testele sunt compilate ca teste Java/Kotlin obișnuite și rulate prin JUnit. Acest lucru oferă un ciclu de feedback de câteva secunde în loc de minute.
Robolectric suportă toate versiunile Android începând cu API 16 (Android 4.1) până la ultima versiune stabilă. Pentru fiecare versiune este furnizat un set corespunzător de obiecte shadow care emulează comportamentul exact al acelei versiuni de platformă pe care este testată aplicația.
Arhitectura Robolectric se bazează pe mecanismul de interceptare a apelurilor prin înlocuirea classloader-ului. Când testul apelează o metodă Android SDK, Robolectric interceptează apelul și îl direcționează către obiectul shadow. Obiectul shadow este o clasă Java care imită comportamentul real al componentei Android, dar funcționează fără platforma nativă.
Obiectele shadow implementează metodele cheie ale claselor originale Android. De exemplu, ShadowTextView imită metodele getText(), setText(), getCurrentTextColor() și altele. La apelul textView.setText("Hello") shadow salvează șirul și îl returnează la apelul getText(). Acest lucru izolează testele de randarea reală și de serviciile de sistem.
Robolectric suportă peste 200 de clase shadow care acoperă componentele principale Android SDK: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager și multe altele. Obiectele shadow urmează aceeași ierarhie de moștenire ca și clasele originale Android.
Instalarea Robolectric într-un proiect Gradle necesită adăugarea dependenței testImplementation "org.robolectric:robolectric:4.x". De asemenea, trebuie specificată configurația android:sdk în fișierul build.gradle și adăugat android:testInstrumentationRunner. Pentru lucrul cu Robolectric nu este necesar pluginul android-test.
După adăugarea dependenței, trebuie configurat directorul pentru manifest, resurse și active. Robolectric găsește automat AndroidManifest.xml, dar poate fi necesară specificarea manuală a căii prin adnotarea @Config sau proprietăți de sistem. Pentru proiecte multi-modul, configurarea se face separat pentru fiecare modul.
// build.gradle — configurarea 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'
}
Adnotarea @Config permite suprascrierea parametrilor testului: sdk (versiunea API), manifest (calea către manifest), qualifiers (configurarea ecranului, limba). Acest lucru este util pentru testarea comportamentului aplicației pe diferite versiuni Android, orientări ale ecranului și localizări.
Testele Robolectric se scriu ca teste unitare obișnuite cu @RunWith(RobolectricTestRunner.class) pentru JUnit 4 sau prin RobolectricExtension pentru JUnit 5. ActivityController gestionează ciclul de viață al Activity: create(), start(), resume(), pause(), stop(), destroy(). Acest lucru permite testarea detaliată a fiecărei tranziții de stare.
Pentru testarea Activity se utilizează ActivityController care parcurge secvențial etapele ciclului de viață. Accesul la Activity se face prin controller.get(). Toate componentele de vizualizare sunt accesibile prin findViewById, ca într-o aplicație reală. Obiectele shadow permit verificarea textelor, vizibilității, culorilor și altor atribute ale vizualizării.
@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 interceptează apelurile startActivity() și permite verificarea intenturilor trimise prin ShadowActivity. Acest lucru oferă posibilitatea testării navigației: verificarea că la apăsarea unui buton se trimite un Intent cu Action, Data și parametrii Extra corecți.
@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 și emulatorul rezolvă sarcini diferite. Robolectric este ideal pentru teste unitare rapide, verificarea logicii UI, a componentelor de afaceri și a depozitelor. Emulatorul este necesar pentru testele instrumentale, verificarea integrării cu API, testarea camerei, senzorilor și performanței.
| Caracteristică | Robolectric | Emulator |
|---|---|---|
| Viteză | ~5 sec pentru 100 de teste | ~5 min pentru 100 de teste |
| Pornire | Fără construire APK | Necesită construire APK |
| API real | Shadow-emulare | Android SDK nativ |
| Out-of-the-box | Doar JUnit | Orice framework |
Robolectric este excelent pentru testarea ViewModel, Repository și UseCase — componente care utilizează Android SDK dar nu necesită UI real. ViewModel se testează printr-un test JUnit obișnuit cu RobolectricExtension, componentele ciclului de viață (LiveData, StateFlow) funcționând în mediul shadow fără mockuri.
Robolectric suportă LiveData din cutie: se poate abona la LiveData în test, schimba starea prin ViewModel și verifica valoarea emisă. Pentru operații asincrone se utilizează InstantTaskExecutorRule sau runBlocking pentru corutine. Acest lucru elimină necesitatea de a face mock la componentele arhitecturale.
@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)
}
}
Dacă obiectele shadow standard Robolectric nu acoperă clasa Android SDK necesară, se poate crea un Shadow personalizat. Pentru aceasta se creează o clasă cu adnotarea @Implements(ClassName.class) și se implementează metodele necesare cu @Implementation. Shadow-urile personalizate se înregistrează prin @Config(shadows = [CustomShadow::class]).
Robolectric suportă testarea ContentProvider prin Robolectric.buildContentProvider(). Se pot verifica operațiile CRUD, query cu potrivire URI și gestionarea drepturilor de acces. Resursele (șiruri, culori, dimensiuni) sunt de asemenea accesibile prin RuntimeEnvironment.application.resources, permițând testarea codului dependent de resurse.
Trecerea de la testele instrumentale la Robolectric necesită schimbarea abordării. Testele instrumentale (AndroidJUnit4) verifică comportamentul real pe emulator, Robolectric — logica izolată în mediul shadow. Se recomandă acoperirea logicii de afaceri cu teste Robolectric, iar testele instrumentale să fie păstrate pentru scenarii de integrare.
La migrare trebuie: înlocuit AndroidJUnit4 cu RobolectricTestRunner, adăugat @Config cu versiunea SDK țintă, înlocuit ActivityTestRule cu ActivityController și mutate dependențele din androidTestImplementation în testImplementation. Mockurile (MockK, Mockito) funcționează cu Robolectric fără modificări — nu depind de platformă.
Robolectric nu suportă: testarea camerei (CameraX), NFC, Bluetooth, biometriei, lucrul cu fișiere reale și biblioteci native. Pentru aceste scenarii sunt necesare teste instrumentale pe emulator. Robolectric nici nu reproduce randarea reală — testele de layout este mai bine să fie executate prin Compose Test Rule sau Espresso. Totuși, pentru verificarea logicii de afaceri, navigației și stărilor ViewModel, Robolectric înlocuiește complet emulatorul cu o accelerare de 10 ori a rulării.
Robolectric necesită JDK 11 sau mai nou și este compatibil cu AGP (Android Gradle Plugin) de la 7.0 până la ultima versiune stabilă. Managerul SDK Robolectric descarcă automat versiunile necesare Android API la prima pornire — aceasta este o operație unică. Pentru serverele CI se recomandă descărcarea prealabilă a SDK-ului prin sdkmanager pentru a evita întârzierile la prima rulare a testelor. Actualizarea Robolectric la o versiune nouă de obicei nu necesită modificări în codul testelor, ci doar actualizarea numărului dependenței în build.gradle.
Robolectric este compatibil cu framework-urile populare de mock: MockK pentru Kotlin și Mockito pentru Java. Mockurile sunt utilizate pentru izolarea dependențelor: depozite, clienți API, SharedPreferences. Regula principală — nu faceți mock la clasele Android SDK, pentru aceasta există obiecte shadow. Faceți mock doar la straturile aplicației: UseCase, Repository, DataSource și alte componente ale logicii de afaceri. O astfel de combinație de obiecte shadow și mockuri oferă flexibilitate maximă cu costuri minime de scriere a testelor.
Întrebări frecvente
Espresso este un framework instrumental care rulează pe emulator sau dispozitiv. Robolectric este un framework unitar care rulează pe JVM. Espresso testează comportamentul real, Robolectric — logica izolată în mediul shadow. Se completează reciproc.
Da, Robolectric suportă Jetpack Compose începând cu versiunea 4.8. Testele componentelor Compose se execută cu ajutorul ComposeTestRule, similar cu emulatorul. Totuși, testele Compose pe Robolectric nu verifică randarea reală — doar logica compoziției.
Robolectric suportă proiecte multi-modul. Fiecare modul se configurează separat cu specificarea propriului manifest și a resurselor. Pentru modulele fără componente UI este suficient un modul de bibliotecă fără plugin android. În proiecte mari cu zeci de module, testele Robolectric ale fiecărui modul rulează în paralel, oferind un câștig suplimentar de viteză față de rularea secvențială pe emulator.
Problema cu resursele apare dacă în build.gradle nu este specificat unitTests.includeAndroidResources = true sau lipsește adnotarea @Config cu calea corectă către manifest. Robolectric utilizează resursele compilate din build/intermediates.
Testele Robolectric se depanează ca testele Java/Kotlin obișnuite în Android Studio. Sunt disponibile breakpoint, step-through debug, inspectarea obiectelor shadow și a stării lor. Logarea se activează prin -Drobolectric.logging=debug în opțiunile VM.
Rezumat
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și