Robolectric — шта је то, принципи рада и јединично тестирање Android-а

Аутор: IT Sectr Објављено: 2026-04-09 Време читања: 8 мин

Robolectric је оквир за јединично тестирање Android апликација који омогућава покретање тестова директно на JVM-у без емулатора или физичког уређаја. Он пресреће позиве Android SDK-а и пружа shadow-објекте који емулирају понашање стварних компоненти. Према Robolectric Documentation, 2025, shadow-објекти замењују око 15 хиљада класа Android API-ја, обезбеђујући изолацију тестова од платформе.

Главно

  • Robolectric — оквир за јединично тестирање Android-а без емулатора, који ради на JVM-у
  • Shadow-објекти пресрећу позиве Android SDK-а и емулирају понашање система
  • Интеграција са JUnit 4 и 5 омогућава коришћење стандардних тест-runner-а
  • Тестови се извршавају за секунде, а не минуте, као у емулатору
  • Подршка за Jetpack Compose, фрагменте, интенте, ContentProvider и ресурсе

Шта је Robolectric

Robolectric је open-source оквир, креиран 2010. године за убрзање тестирања Android апликација. Уместо покретања на емулатору или уређају, Robolectric пружа shadow-имплементације класа Android SDK-а које раде директно на Java Virtual Machine (JVM). Ово омогућава извршавање хиљада тестова за секунде.

Проблем који Robolectric решава

Традиционално Android тестирање захтева покретање апликације на емулатору, што траје 3–10 минута за изградњу APK-а, инсталацију и покретање. Robolectric елиминише овај корак: тестови се компајлирају као обични Java/Kotlin тестови и покрећу се преко JUnit-а. Ово даје повратну спрегу у неколико секунди уместо минута.

Подржане верзије Android-а

Robolectric подржава све верзије Android-а почев од API 16 (Android 4.1) до последње стабилне. За сваку верзију се обезбеђује одговарајући скуп shadow-објеката који емулирају понашање управо оне верзије платформе на којој се тестира апликација.

Архитектура и shadow-објекти

Архитектура Robolectric-а се заснива на механизму пресретања позива кроз замену classloader-а. Када тест позове метод Android SDK-а, Robolectric пресреће позив и усмерава га ка shadow-објекту. Shadow-објекат је Java класа која имитира стварно понашање Android компоненте, али ради без нативне платформе.

Како shadow раде

Shadow-објекти имплементирају кључне методе оригиналних Android класа. На пример, ShadowTextView имитира методе getText(), setText(), getCurrentTextColor() и друге. При позиву textView.setText(„Hello“) shadow чува стринг и враћа га при позиву getText(). Ово изолује тестове од стварног рендеровања и системских сервиса.

Shadow-хијерархија

Robolectric подржава преко 200 shadow-класа које покривају главне компоненте Android SDK-а: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager и многе друге. Shadow-објекти прате исту хијерархију наслеђивања као и оригиналне Android класе.

Инсталација и подешавање Robolectric-а

Инсталација Robolectric-а у Gradle пројекат захтева додавање зависности testImplementation „org.robolectric:robolectric:4.x“. Такође је потребно навести конфигурацију android:sdk у датотеци build.gradle и додати android:testInstrumentationRunner. За рад са Robolectric-ом није потребан android-test додатак.

Основна Gradle конфигурација

Након додавања зависности, потребно је конфигурисати директоријум за манифест, ресурсе и асете. Robolectric аутоматски проналази AndroidManifest.xml, али може бити потребно ручно навести путању кроз @Config анотацију или системска својства. За вишемодулне пројекте конфигурација се поставља одвојено за сваки модул.

groovy
// build.gradle — подешавање 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

Анотација @Config омогућава преиначавање параметара теста: sdk (верзија API-ја), manifest (путања до манифеста), qualifiers (конфигурација екрана, језик). Ово је корисно за тестирање понашања апликације на различитим верзијама Android-а, оријентацијама екрана и локализацијама.

Писање тестова са Robolectric-ом

Robolectric тестови се пишу као обични јединични тестови са @RunWith(RobolectricTestRunner.class) за JUnit 4 или кроз RobolectricExtension за JUnit 5. ActivityController управља животним циклусом Activity-ја: create(), start(), resume(), pause(), stop(), destroy(). Ово омогућава детаљно тестирање сваког прелаза стања.

Тестирање Activity-ја

За тестирање Activity-ја се користи ActivityController који сукцесивно пролази кроз фазе животног циклуса. Приступ Activity-ју се остварује кроз controller.get(). Све компоненте прегледа су доступне кроз findViewById, као у стварној апликацији. Shadow-објекти омогућавају проверу текстова, видљивости, боја и других атрибута приказа.

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

Тестирање интента и навигације

Robolectric пресреће позиве startActivity() и омогућава проверу послатих интената кроз ShadowActivity. Ово даје могућност тестирања навигације: провера да се при клику на дугме шаље Intent са исправним Action, Data и Extra параметрима.

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 против емулатора

Robolectric и емулатор решавају различите задатке. Robolectric је идеалан за брзе јединичне тестове, проверу логике UI-ја, пословних компоненти и репозиторијума. Емулатор је неопходан за инструментационе тестове, проверу интеграције са API-јем, тестирање камере, сензора и перформанси.

КарактеристикаRobolectricЕмулатор
Брзина~5 сек за 100 тестова~5 мин за 100 тестова
ПокретањеБез изградње APK-аЗахтева изградњу APK-а
Стварни APIShadow-емулацијаИзворни Android SDK
Out-of-the-boxСамо JUnitБило који оквири

Тестирање ViewModel-а и Repository-ја

Robolectric је одличан за тестирање ViewModel-а, Repository-ја и UseCase-а — компоненти које користе Android SDK, али не захтевају стварни UI. ViewModel се тестира кроз обичан JUnit тест са RobolectricExtension, при чему компоненте животног циклуса (LiveData, StateFlow) раде у shadow-окружењу без мокова.

Тестирање LiveData-е

Robolectric подржава LiveData из кутије: могуће је претплатити се на LiveData у тесту, променити стање кроз ViewModel и проверити емитовану вредност. За асинхроне операције се користи InstantTaskExecutorRule или runBlocking за корутине. Ово елиминише потребу за моковањем архитектонских компоненти.

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

Прилагођени shadow-објекти

Ако стандардни shadow-објекти Robolectric-а не покривају потребну Android SDK класу, може се креирати прилагођени Shadow. За то се креира класа са анотацијом @Implements(ClassName.class) и имплементирају потребне методе са @Implementation. Прилагођени shadow-и се региструју кроз @Config(shadows = [CustomShadow::class]).

Тестирање ContentProvider-а и Resources-а

Robolectric подржава тестирање ContentProvider-а кроз Robolectric.buildContentProvider(). Могуће је проверити CRUD операције, query са URI подударањем и обраду права приступа. Ресурси (стрингови, боје, величине) су такође доступни кроз RuntimeEnvironment.application.resources, што омогућава тестирање кода зависног од ресурса.

Миграција са емулатора на Robolectric

Прелазак са инструментационих тестова на Robolectric захтева промену приступа. Инструментациони тестови (AndroidJUnit4) проверавају стварно понашање на емулатору, Robolectric — изоловану логику у shadow-окружењу. Препоручује се покривање пословне логике Robolectric тестовима, а инструментационе тестове оставити за интеграционе сценарије.

Адаптација постојећих тестова

При миграцији треба: заменити AndroidJUnit4 са RobolectricTestRunner, додати @Config са циљаном верзијом SDK-а, заменити ActivityTestRule са ActivityController, и преместити зависности из androidTestImplementation у testImplementation. Мокови (MockK, Mockito) раде са Robolectric-ом без измена — не зависе од платформе.

Ограничења при миграцији

Robolectric не подржава: тестирање камере (CameraX), NFC, Bluetooth, биометрије, рад са стварним датотекама и изворним библиотекама. За ове сценарије су потребни инструментациони тестови на емулатору. Robolectric такође не репродукује стварно рендеровање — тестове изгледа је боље извршавати кроз Compose Test Rule или Espresso. Међутим, за проверу пословне логике, навигације и стања ViewModel-а Robolectric потпуно замењује емулатор са 10-струким убрзањем извршавања.

Компатибилност са Java и Kotlin верзијама

Robolectric захтева JDK 11 или новији и компатибилан је са AGP (Android Gradle Plugin) од 7.0 до последње стабилне верзије. SDK менаџер Robolectric-а аутоматски преузима потребне верзије Android API-ја при првом покретању — ово је једнократна операција. За CI сервере се препоручује претходно преузимање SDK-а путем sdkmanager-а како би се избегла кашњења при првом покретању тестова. Ажурирање Robolectric-а на нову верзију обично не захтева измене у коду тестова, само ажурирање броја зависности у build.gradle-у.

Интеграција са MockK и Mockito

Robolectric је компатибилан са популарним mocking оквирима: MockK за Kotlin и Mockito за Java. Мокови се користе за изолацију зависности: репозиторијума, API клијената, SharedPreferences-а. Главно правило — не моковати Android SDK класе, за то постоје shadow-објекти. Мокујте само слојеве апликације: UseCase, Repository, DataSource и друге компоненте пословне логике. Таква комбинација shadow-објеката и мокова даје максималну флексибилност уз минималне трошкове писања тестова.

Често постављана питања

По чему се Robolectric разликује од Espressa?

Espresso је инструментациони оквир који се покреће на емулатору или уређају. Robolectric је јединични оквир који ради на JVM-у. Espresso тестира стварно понашање, Robolectric — изоловану логику у shadow-окружењу. Они се допуњују.

Може ли се тестирати Jetpack Compose са Robolectric-ом?

Да, Robolectric подржава Jetpack Compose од верзије 4.8. Тестови Compose компоненти се извршавају помоћу ComposeTestRule, слично емулатору. Међутим, Compose тестови на Robolectric-у не проверавају стварно рендеровање — само логику композиције.

Како Robolectric ради са Gradle модулима?

Robolectric подржава вишемодулне пројекте. Сваки модул се подешава одвојено са навођењем свог манифеста и ресурса. За модуле без UI компоненти довољан је библиотечки модул без android додатка. У великим пројектима са десетинама модула, Robolectric тестови сваког модула се покрећу паралелно, што даје додатну предност у брзини у поређењу са секвенцијалним покретањем на емулатору.

Зашто Robolectric можда не може да пронађе ресурсе?

Проблем са ресурсима настаје ако у build.gradle није наведено unitTests.includeAndroidResources = true или недостаје @Config анотација са исправном путањом до манифеста. Robolectric користи компајлиране ресурсе из build/intermediates.

Како отклањати грешке у Robolectric тестовима?

Robolectric тестови се отклањају као обични Java/Kotlin тестови у Android Studio-у. Доступни су breakpoint, step-through debug, инспекција shadow-објеката и њиховог стања. Логовање се укључује кроз -Drobolectric.logging=debug у VM опцијама.

Закључак

  • Robolectric — оквир за брзо јединично тестирање Android-а на JVM-у без емулатора
  • Shadow-објекти замењују преко 200 Android SDK класа, емулирајући њихово понашање
  • Животни циклус Activity-ја и Fragment-а се управља кроз ActivityController са провером стања
  • Тестирање интената кроз ShadowActivity омогућава проверу навигације и преноса података
  • Интеграција са JUnit-ом и Gradle-ом не захтева додатне инструментационе runner-е
  • Анотација @Config одређује верзију API-ја, језик, конфигурацију екрана и ресурсе
  • Robolectric и Espresso се допуњују: брзи јединични тестови против инструментационих

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође