Robolectric ist ein Framework für Unit-Tests von Android-Anwendungen, mit dem Tests direkt auf der JVM ohne Emulator oder physisches Gerät ausgeführt werden können. Es fängt Android-SDK-Aufrufe ab und stellt Shadow-Objekte bereit, die das Verhalten realer Komponenten emulieren. Laut Robolectric Documentation, 2025 ersetzen Shadow-Objekte etwa 15.000 Android-API-Klassen und gewährleisten so die Isolierung der Tests von der Plattform.
Das Wichtigste
Robolectric ist ein Open-Source-Framework, das 2010 entwickelt wurde, um Android-Anwendungstests zu beschleunigen. Anstatt auf einem Emulator oder Gerät zu laufen, bietet Robolectric Shadow-Implementierungen von Android-SDK-Klassen, die direkt auf der Java Virtual Machine (JVM) ausgeführt werden. So können Tausende von Tests in Sekunden ausgeführt werden.
Traditionelle Android-Tests erfordern das Ausführen der Anwendung auf einem Emulator, was 3–10 Minuten für den APK-Build, die Installation und den Start dauert. Robolectric eliminiert diesen Schritt: Tests werden als normale Java/Kotlin-Tests kompiliert und über JUnit ausgeführt. Dies ermöglicht eine Rückkopplungsschleife von Sekunden statt Minuten.
Robolectric unterstützt alle Android-Versionen ab API 16 (Android 4.1) bis zur neuesten stabilen Version. Für jede Version wird ein entsprechender Satz von Shadow-Objekten bereitgestellt, die das Verhalten der jeweiligen Plattformversion emulieren, auf der die Anwendung getestet wird.
Die Architektur von Robolectric basiert auf dem Abfangen von Aufrufen durch Austausch des Classloaders. Wenn ein Test eine Android-SDK-Methode aufruft, fängt Robolectric den Aufruf ab und leitet ihn an ein Shadow-Objekt weiter. Ein Shadow-Objekt ist eine Java-Klasse, die das reale Verhalten einer Android-Komponente nachahmt, aber ohne die native Plattform arbeitet.
Shadow-Objekte implementieren die wichtigsten Methoden der ursprünglichen Android-Klassen. Beispielsweise ahmt ShadowTextView Methoden wie getText(), setText(), getCurrentTextColor() und andere nach. Wenn textView.setText("Hallo") aufgerufen wird, speichert der Shadow die Zeichenfolge und gibt sie bei Aufruf von getText() zurück. Dies isoliert die Tests von echtem Rendering und Systemdiensten.
Robolectric unterstützt über 200 Shadow-Klassen, die die wichtigsten Android-SDK-Komponenten abdecken: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager und viele andere. Shadow-Objekte folgen derselben Vererbungshierarchie wie die ursprünglichen Android-Klassen.
Die Installation von Robolectric in einem Gradle-Projekt erfordert das Hinzufügen der Abhängigkeit testImplementation "org.robolectric:robolectric:4.x". Außerdem muss die androidsdk-Konfiguration in der build.gradle-Datei angegeben und die Auflösung android:testInstrumentationRunner hinzugefügt werden. Für die Arbeit mit Robolectric ist kein Android-Test-Plugin erforderlich.
Nach dem Hinzufügen der Abhängigkeit muss das Verzeichnis für das Manifest, die Ressourcen und Assets konfiguriert werden. Robolectric findet AndroidManifest.xml automatisch, aber der Pfad kann manuell über die @Config-Annotation oder Systemeigenschaften angegeben werden. Bei Multi-Modul-Projekten wird die Konfiguration für jedes Modul separat festgelegt.
// build.gradle — Robolectric-Konfiguration
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'
}
Die @Config-Annotation ermöglicht das Überschreiben von Testparametern: sdk (API-Version), manifest (Pfad zum Manifest), qualifiers (Bildschirmkonfiguration, Sprache). Dies ist nützlich, um das Anwendungsverhalten auf verschiedenen Android-Versionen, Bildschirmausrichtungen und Lokalisierungen zu testen.
Robolectric-Tests werden als normale Unit-Tests mit @RunWith(RobolectricTestRunner.class) für JUnit 4 oder über RobolectricExtension für JUnit 5 geschrieben. ActivityController verwaltet den Activity-Lebenszyklus: create(), start(), resume(), pause(), stop(), destroy(). Dies ermöglicht das detaillierte Testen jedes Zustandsübergangs.
Zum Testen einer Activity wird ActivityController verwendet, der sequenziell die Lebenszyklusphasen durchläuft. Der Zugriff auf die Activity erfolgt über controller.get(). Alle View-Komponenten sind wie in einer echten Anwendung über findViewById zugänglich. Shadow-Objekte ermöglichen die Überprüfung von Texten, Sichtbarkeit, Farben und anderen View-Attributen.
@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 fängt startActivity()-Aufrufe ab und ermöglicht die Überprüfung gesendeter Intents über ShadowActivity. Dies ermöglicht das Testen der Navigation: Überprüfen, ob beim Klicken auf eine Schaltfläche ein Intent mit den korrekten Action-, Data- und Extra-Parametern gesendet wird.
@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 und der Emulator lösen unterschiedliche Aufgaben. Robolectric ist ideal für schnelle Unit-Tests, Überprüfung der UI-Logik, Geschäftskomponenten und Repositories. Der Emulator wird für Instrumentierungstests, Integrationsprüfungen mit APIs, Kameratests, Sensoren und Leistungstests benötigt.
| Eigenschaft | Robolectric | Emulator |
|---|---|---|
| Geschwindigkeit | ~5 Sek pro 100 Tests | ~5 Min pro 100 Tests |
| Start | Ohne APK-Build | APK-Build erforderlich |
| Echte API | Shadow-Emulation | Natives Android SDK |
| Out-of-the-box | Nur JUnit | Beliebige Frameworks |
Robolectric eignet sich hervorragend zum Testen von ViewModel, Repository und UseCase — Komponenten, die das Android SDK verwenden, aber keine echte UI benötigen. ViewModel wird über einen regulären JUnit-Test mit RobolectricExtension getestet, während Lebenszykluskomponenten (LiveData, StateFlow) in der Shadow-Umgebung ohne Mocks funktionieren.
Robolectric unterstützt LiveData out-of-the-box: Sie können LiveData im Test abonnieren, den Zustand über ViewModel ändern und den emittierten Wert überprüfen. Für asynchrone Operationen wird InstantTaskExecutorRule oder runBlocking für Coroutinen verwendet. Dadurch entfällt die Notwendigkeit, Architekturkomponenten zu mocken.
@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)
}
}
Falls die standardmäßigen Shadow-Objekte von Robolectric eine benötigte Android-SDK-Klasse nicht abdecken, können Sie einen benutzerdefinierten Shadow erstellen. Dazu erstellen Sie eine Klasse mit der @Implements(ClassName.class)-Annotation und implementieren die benötigten Methoden mit @Implementation. Benutzerdefinierte Shadows werden über @Config(shadows = [CustomShadow::class]) registriert.
Robolectric unterstützt das Testen von ContentProvider über Robolectric.buildContentProvider(). Sie können CRUD-Operationen, Abfragen mit URI-Matching und Zugriffsrechteverwaltung überprüfen. Ressourcen (Zeichenfolgen, Farben, Abmessungen) sind auch über RuntimeEnvironment.application.resources zugänglich, was das Testen von ressourcenabhängigem Code ermöglicht.
Der Übergang von Instrumentierungstests zu Robolectric erfordert eine Änderung des Ansatzes. Instrumentierungstests (AndroidJUnit4) überprüfen das reale Verhalten auf dem Emulator, während Robolectric isolierte Logik in einer Shadow-Umgebung überprüft. Es wird empfohlen, die Geschäftslogik mit Robolectric-Tests abzudecken und Instrumentierungstests für Integrationsszenarien zu behalten.
Bei der Migration müssen Sie: AndroidJUnit4 durch RobolectricTestRunner ersetzen, @Config mit der Ziel-SDK-Version hinzufügen, ActivityTestRule durch ActivityController ersetzen und Abhängigkeiten von androidTestImplementation nach testImplementation verschieben. Mocks (MockK, Mockito) funktionieren ohne Änderungen mit Robolectric — sie sind plattformunabhängig.
Robolectric unterstützt nicht: Testen der Kamera (CameraX), NFC, Bluetooth, Biometrie, Arbeiten mit echten Dateien und nativen Bibliotheken. Diese Szenarien erfordern Instrumentierungstests auf dem Emulator. Robolectric reproduziert auch kein echtes Rendering — Layouttests werden besser über Compose Test Rule oder Espresso durchgeführt. Für die Überprüfung von Geschäftslogik, Navigation und ViewModel-Zuständen ersetzt Robolectric jedoch den Emulator vollständig mit 10-facher Beschleunigung.
Robolectric erfordert JDK 11 oder höher und ist mit AGP (Android Gradle Plugin) von 7.0 bis zur neuesten stabilen Version kompatibel. Der SDK-Manager von Robolectric lädt beim ersten Start automatisch die erforderlichen Android-API-Versionen herunter — dies ist ein einmaliger Vorgang. Für CI-Server wird empfohlen, das SDK vorab über sdkmanager zu laden, um Verzögerungen beim ersten Testlauf zu vermeiden. Ein Update von Robolectric auf eine neue Version erfordert in der Regel keine Änderungen am Testcode, sondern nur eine Aktualisierung der Abhängigkeitsnummer in build.gradle.
Robolectric ist mit gängigen Mocking-Frameworks kompatibel: MockK für Kotlin und Mockito für Java. Mocks werden zur Isolierung von Abhängigkeiten verwendet: Repositories, API-Clients, SharedPreferences. Die Hauptregel ist, keine Android-SDK-Klassen zu mocken — dafür gibt es Shadow-Objekte. Mocken Sie nur Anwendungsschichten: UseCase, Repository, DataSource und andere Geschäftslogikkomponenten. Diese Kombination aus Shadow-Objekten und Mocks bietet maximale Flexibilität bei minimalem Testschreibaufwand.
Häufig gestellte Fragen
Espresso ist ein Instrumentierungs-Framework, das auf einem Emulator oder Gerät läuft. Robolectric ist ein Unit-Test-Framework, das auf der JVM läuft. Espresso testet das reale Verhalten, Robolectric testet isolierte Logik in einer Shadow-Umgebung. Sie ergänzen sich gegenseitig.
Ja, Robolectric unterstützt Jetpack Compose ab Version 4.8. Compose-Komponententests werden mit ComposeTestRule ausgeführt, ähnlich wie beim Emulator. Allerdings überprüfen Compose-Tests auf Robolectric kein echtes Rendering — nur die Kompositionslogik.
Robolectric unterstützt Multi-Modul-Projekte. Jedes Modul wird separat mit eigenem Manifest und eigenen Ressourcen konfiguriert. Für Module ohne UI-Komponenten reicht ein Bibliotheksmodul ohne Android-Plugin aus. In großen Projekten mit Dutzenden von Modulen werden die Robolectric-Tests jedes Moduls parallel ausgeführt, was einen zusätzlichen Geschwindigkeitsvorteil gegenüber der sequenziellen Ausführung auf dem Emulator bietet.
Das Ressourcenproblem tritt auf, wenn in der build.gradle nicht unitTests.includeAndroidResources = true gesetzt ist oder die @Config-Annotation mit dem korrekten Pfad zum Manifest fehlt. Robolectric verwendet kompilierte Ressourcen aus build/intermediates.
Robolectric-Tests werden wie normale Java/Kotlin-Tests in Android Studio debuggt. Breakpoints, Step-through-Debugging und Inspektion von Shadow-Objekten und deren Zustand sind verfügbar. Die Protokollierung wird über -Drobolectric.logging=debug in den VM-Optionen aktiviert.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch