Robolectric — vad det är, arbetsprinciper och enhetstestning av Android

Författare: IT Sectr Publicerad: 2026-04-09 Lästid: 8 min

Robolectric är ett ramverk för enhetstestning av Android-applikationer som gör det möjligt att köra tester direkt på JVM utan emulator eller fysisk enhet. Det fångar upp anrop till Android SDK och tillhandahåller shadow-objekt som emulerar beteendet hos verkliga komponenter. Enligt Robolectric Documentation, 2025 ersätter shadow-objekt cirka 15 000 klasser i Android API, vilket säkerställer isolering av tester från plattformen.

Huvudpunkter

  • Robolectric — ramverk för enhetstestning av Android utan emulator, som körs på JVM
  • Shadow-objekt fångar upp Android SDK-anrop och emulerar systembeteende
  • Integration med JUnit 4 och 5 möjliggör användning av standardtestkörare
  • Tester utförs på sekunder, inte minuter som i emulatorn
  • Stöd för Jetpack Compose, fragment, intent, ContentProvider och resurser

Vad är Robolectric

Robolectric är ett open source-ramverk, skapat 2010 för att påskynda testning av Android-applikationer. Istället för att köras på en emulator eller enhet tillhandahåller Robolectric shadow-implementationer av Android SDK-klasser som fungerar direkt på Java Virtual Machine (JVM). Detta gör det möjligt att utföra tusentals tester på sekunder.

Problemet som Robolectric löser

Traditionell Android-testning kräver att applikationen körs på en emulator, vilket tar 3–10 minuter för att bygga APK, installera och starta. Robolectric eliminerar detta steg: tester kompileras som vanliga Java/Kotlin-tester och körs via JUnit. Detta ger en återkopplingscykel på några sekunder istället för minuter.

Stödda Android-versioner

Robolectric stöder alla Android-versioner från API 16 (Android 4.1) till den senaste stabila versionen. För varje version tillhandahålls en motsvarande uppsättning shadow-objekt som emulerar beteendet hos just den plattformsversion som applikationen testas på.

Arkitektur och shadow-objekt

Robolectrics arkitektur är baserad på en mekanism för att fånga upp anrop genom att byta ut classloader. När ett test anropar en metod i Android SDK fångar Robolectric upp anropet och skickar det till shadow-objektet. Shadow-objekt är en Java-klass som imiterar det verkliga beteendet hos en Android-komponent men fungerar utan native-plattform.

Hur shadow fungerar

Shadow-objekt implementerar nyckelmetoder i de ursprungliga Android-klasserna. Till exempel imiterar ShadowTextView metoderna getText(), setText(), getCurrentTextColor() och andra. Vid anrop av textView.setText(“Hello”) sparar shadow strängen och returnerar den vid anrop av getText(). Detta isolerar tester från verklig rendering och systemtjänster.

Shadow-hierarki

Robolectric stöder över 200 shadow-klasser som täcker de viktigaste komponenterna i Android SDK: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager och många andra. Shadow-objekt följer samma arvshierarki som de ursprungliga Android-klasserna.

Installation och konfiguration av Robolectric

Installation av Robolectric i ett Gradle-projekt kräver att man lägger till beroendet testImplementation “org.robolectric:robolectric:4.x”. Man måste också specificera android:sdk-konfigurationen i build.gradle-filen och lägga till android:testInstrumentationRunner. För att arbeta med Robolectric krävs ingen android-test-plugin.

Grundläggande Gradle-konfiguration

Efter att ha lagt till beroendet måste man konfigurera katalogen för manifest, resurser och tillgångar. Robolectric hittar automatiskt AndroidManifest.xml, men det kan vara nödvändigt att manuellt ange sökvägen via @Config-annoteringen eller systemegenskaper. För flermodulprojekt konfigureras varje modul separat.

groovy
// build.gradle — konfiguration av 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'
}

@Config-annotering

@Config-annoteringen gör det möjligt att åsidosätta testparametrar: sdk (API-version), manifest (sökväg till manifest), qualifiers (skärmkonfiguration, språk). Detta är användbart för att testa applikationens beteende på olika Android-versioner, skärmorienteringar och lokaliseringar.

Skriva tester med Robolectric

Robolectric-tester skrivs som vanliga enhetstester med @RunWith(RobolectricTestRunner.class) för JUnit 4 eller via RobolectricExtension för JUnit 5. ActivityController hanterar Activitys livscykel: create(), start(), resume(), pause(), stop(), destroy(). Detta möjliggör detaljerad testning av varje tillståndsövergång.

Testa Activity

För att testa Activity används ActivityController som sekventiellt går igenom livscykelfaserna. Åtkomst till Activity sker via controller.get(). Alla vykomponenter är tillgängliga via findViewById, precis som i en verklig applikation. Shadow-objekt gör det möjligt att kontrollera texter, synlighet, färger och andra vyattribut.

java
@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());
    }
}

Testa intent och navigering

Robolectric fångar upp startActivity()-anrop och gör det möjligt att kontrollera skickade intent via ShadowActivity. Detta ger möjlighet att testa navigering: kontrollera att när en knapp trycks skickas ett Intent med korrekt Action, Data och Extra-parametrar.

java
@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 jämfört med emulator

Robolectric och emulatorn löser olika uppgifter. Robolectric är idealiskt för snabba enhetstester, kontroll av UI-logik, affärskomponenter och datalager. Emulatorn är nödvändig för instrumenteringstester, kontroll av integration med API, testning av kamera, sensorer och prestanda.

EgenskapRobolectricEmulator
Hastighet~5 sek per 100 tester~5 min per 100 tester
StartUtan APK-byggeKräver APK-bygge
Verkligt APIShadow-emuleringNative Android SDK
Out-of-the-boxEndast JUnitValfritt ramverk

Testa ViewModel och Repository

Robolectric är utmärkt för att testa ViewModel, Repository och UseCase — komponenter som använder Android SDK men inte kräver verkligt UI. ViewModel testas via ett vanligt JUnit-test med RobolectricExtension, där livscykelkomponenter (LiveData, StateFlow) fungerar i shadow-miljön utan mockar.

Testa LiveData

Robolectric stöder LiveData direkt: man kan prenumerera på LiveData i testet, ändra tillstånd via ViewModel och kontrollera det emitterade värdet. För asynkrona operationer används InstantTaskExecutorRule eller runBlocking för korutiner. Detta eliminerar behovet av att mocka arkitekturkomponenter.

kotlin
@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)
    }
}

Anpassade shadow-objekt

Om Robolectrics standard-shadow-objekt inte täcker den nödvändiga Android SDK-klassen kan man skapa en anpassad Shadow. För detta skapar man en klass med @Implements(ClassName.class)-annoteringen och implementerar de nödvändiga metoderna med @Implementation. Anpassade shadow registreras via @Config(shadows = [CustomShadow::class]).

Testa ContentProvider och Resources

Robolectric stöder testning av ContentProvider via Robolectric.buildContentProvider(). Man kan kontrollera CRUD-operationer, frågor med URI-matchning och hantering av åtkomsträttigheter. Resurser (strängar, färger, storlekar) är också tillgängliga via RuntimeEnvironment.application.resources, vilket möjliggör testning av resursberoende kod.

Migrering från emulator till Robolectric

Övergång från instrumenteringstester till Robolectric kräver en förändring av tillvägagångssättet. Instrumenteringstester (AndroidJUnit4) kontrollerar verkligt beteende på emulatorn, Robolectric — isolerad logik i shadow-miljön. Det rekommenderas att täcka affärslogik med Robolectric-tester och behålla instrumenteringstester för integrationsscenarier.

Anpassning av befintliga tester

Vid migrering behöver man: ersätta AndroidJUnit4 med RobolectricTestRunner, lägga till @Config med mål-SDK-versionen, ersätta ActivityTestRule med ActivityController och flytta beroenden från androidTestImplementation till testImplementation. Mockar (MockK, Mockito) fungerar med Robolectric utan förändringar — de är inte plattformsberoende.

Begränsningar vid migrering

Robolectric stöder inte: testning av kamera (CameraX), NFC, Bluetooth, biometri, arbete med verkliga filer och native-bibliotek. För dessa scenarier krävs instrumenteringstester på emulatorn. Robolectric återger inte heller verklig rendering — layouttester är bättre att utföra via Compose Test Rule eller Espresso. För kontroll av affärslogik, navigering och ViewModel-tillstånd ersätter Robolectric dock helt emulatorn med 10-faldig hastighetsökning.

Kompatibilitet med Java- och Kotlin-versioner

Robolectric kräver JDK 11 eller senare och är kompatibelt med AGP (Android Gradle Plugin) från 7.0 till den senaste stabila versionen. Robolectrics SDK-hanterare laddar automatiskt ner nödvändiga Android API-versioner vid första start — detta är en engångsoperation. För CI-servrar rekommenderas att ladda ner SDK i förväg via sdkmanager för att undvika förseningar vid första testkörningen. Uppdatering av Robolectric till en ny version kräver vanligtvis inga ändringar i testkoden, endast uppdatering av beroendenumret i build.gradle.

Integration med MockK och Mockito

Robolectric är kompatibelt med populära mock-ramverk: MockK för Kotlin och Mockito för Java. Mockar används för att isolera beroenden: datalager, API-klienter, SharedPreferences. Huvudregeln — mocka inte Android SDK-klasser, för det finns shadow-objekt. Mocka endast applikationslager: UseCase, Repository, DataSource och andra komponenter i affärslogiken. En sådan kombination av shadow-objekt och mockar ger maximal flexibilitet med minimal kostnad för att skriva tester.

Vanliga frågor

Vad är skillnaden mellan Robolectric och Espresso?

Espresso är ett instrumenteringsramverk som körs på emulatorn eller enheten. Robolectric är ett enhetstestramverk som fungerar på JVM. Espresso testar verkligt beteende, Robolectric — isolerad logik i shadow-miljön. De kompletterar varandra.

Kan man testa Jetpack Compose med Robolectric?

Ja, Robolectric stöder Jetpack Compose från version 4.8. Tester av Compose-komponenter utförs med ComposeTestRule, liknande emulatorn. Dock kontrollerar Compose-tester på Robolectric inte verklig rendering — endast kompositionslogik.

Hur fungerar Robolectric med Gradle-moduler?

Robolectric stöder flermodulprojekt. Varje modul konfigureras separat med angivande av eget manifest och resurser. För moduler utan UI-komponenter räcker en biblioteksmodul utan android-plugin. I stora projekt med dussintals moduler körs Robolectric-tester för varje modul parallellt, vilket ger en extra hastighetsfördel jämfört med sekventiell körning på emulatorn.

Varför kan Robolectric inte hitta resurser?

Problemet med resurser uppstår om build.gradle inte har unitTests.includeAndroidResources = true angivet eller om @Config-annoteringen med rätt sökväg till manifestet saknas. Robolectric använder kompilerade resurser från build/intermediates.

Hur felsöker man Robolectric-tester?

Robolectric-tester felsöks som vanliga Java/Kotlin-tester i Android Studio. Brytpunkter, steg-för-steg-felsökning, inspektion av shadow-objekt och deras tillstånd är tillgängliga. Loggning aktiveras via -Drobolectric.logging=debug i VM-alternativ.

Sammanfattning

  • Robolectric — ramverk för snabb enhetstestning av Android på JVM utan emulator
  • Shadow-objekt ersätter över 200 Android SDK-klasser och emulerar deras beteende
  • Livscykel för Activity och Fragment hanteras via ActivityController med tillståndskontroll
  • Intent-testning via ShadowActivity möjliggör kontroll av navigering och dataöverföring
  • Integration med JUnit och Gradle kräver inga ytterligare instrumenteringskörare
  • @Config-annotering anger API-version, språk, skärmkonfiguration och resurser
  • Robolectric och Espresso kompletterar varandra: snabba enhetstester kontra instrumenteringstester

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också