Robolectric — это фреймворк для юнит-тестирования Android-приложений, который позволяет запускать тесты непосредственно на JVM без эмулятора или физического устройства. Он перехватывает вызовы Android SDK и предоставляет shadow-объекты, эмулирующие поведение реальных компонентов. По данным Robolectric Documentation, 2025, shadow-объекты заменяют около 15 тысяч классов Android API, обеспечивая изоляцию тестов от платформы.
Главное
Robolectric — это open-source фреймворк, созданный в 2010 году для ускорения тестирования Android-приложений. Вместо запуска на эмуляторе или устройстве, Robolectric предоставляет shadow-реализации классов Android SDK, которые работают непосредственно на виртуальной машине Java (JVM). Это позволяет выполнять тысячи тестов за секунды.
Традиционное Android-тестирование требует запуска приложения на эмуляторе, что занимает 3–10 минут на сборку APK, установку и запуск. Robolectric устраняет этот шаг: тесты компилируются как обычные Java/Kotlin-тесты и запускаются через JUnit. Это даёт цикл обратной связи в несколько секунд вместо минут.
Robolectric поддерживает все версии Android начиная с API 16 (Android 4.1) и до последней стабильной. Для каждой версии предоставляется соответствующий набор shadow-объектов, которые эмулируют поведение именно той версии платформы, на которой тестируется приложение.
Архитектура Robolectric основана на механизме перехвата вызовов через подмену classloader'а. Когда тест вызывает метод Android SDK, Robolectric перехватывает вызов и направляет его в shadow-объект. Shadow-объект — это Java-класс, который имитирует реальное поведение Android-компонента, но работает без нативной платформы.
Shadow-объекты реализуют ключевые методы оригинальных Android-классов. Например, ShadowTextView имитирует методы getText(), setText(), getCurrentTextColor() и другие. При вызове textView.setText("Hello") shadow сохраняет строку и возвращает её при вызове getText(). Это изолирует тесты от реального рендеринга и системных сервисов.
Robolectric поддерживает более 200 shadow-классов, покрывающих основные компоненты Android SDK: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager и многие другие. Shadow-объекты следуют той же иерархии наследования, что и оригинальные классы Android.
Установка Robolectric в проект Gradle требует добавления зависимости testImplementation "org.robolectric:robolectric:4.x". Также необходимо указать androidsdk-конфигурацию в файле build.gradle и добавить разрешение android:testInstrumentationRunner. Для работы с Robolectric не требуется плагин android-тестов.
После добавления зависимости нужно сконфигурировать директорию для манифеста, ресурсов и ассетов. Robolectric автоматически находит AndroidManifest.xml, но может потребоваться указать путь вручную через @Config-аннотацию или системные свойства. Для мультимодульных проектов конфигурация задаётся отдельно для каждого модуля.
// 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 позволяет переопределить параметры теста: sdk (версия API), manifest (путь к манифесту), qualifiers (конфигурация экрана, язык). Это полезно для тестирования поведения приложения на разных версиях Android, ориентациях экрана и локализациях.
Тесты Robolectric пишутся как обычные юнит-тесты с @RunWith(RobolectricTestRunner.class) для JUnit 4 или через RobolectricExtension для JUnit 5. ActivityController управляет жизненным циклом Activity: create(), start(), resume(), pause(), stop(), destroy(). Это позволяет детально тестировать каждый переход состояния.
Для тестирования Activity используется ActivityController, который последовательно проходит через стадии жизненного цикла. Доступ к Activity осуществляется через controller.get(). Все view-компоненты доступны через findViewById, как в реальном приложении. Shadow-объекты позволяют проверить тексты, видимость, цвета и другие атрибуты вью.
@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-параметрами.
@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 идеален для быстрых юнит-тестов, проверки логики UI, бизнес-компонентов и репозиториев. Эмулятор необходим для инструментационных тестов, проверки интеграции с API, тестирования камеры, датчиков и производительности.
| Характеристика | Robolectric | Эмулятор |
|---|---|---|
| Скорость | ~5 сек на 100 тестов | ~5 мин на 100 тестов |
| Запуск | Без сборки APK | Требуется сборка APK |
| Реальное API | Shadow-эмуляция | Нативный Android SDK |
| Out-of-the-box | Только JUnit | Любые фреймворки |
Robolectric отлично подходит для тестирования ViewModel, Repository и UseCase — компонентов, которые используют Android SDK, но не требуют реального UI. ViewModel тестируется через обычный JUnit-тест с RobolectricExtension, при этом lifecycle-компоненты (LiveData, StateFlow) работают в shadow-среде без моков.
Robolectic поддерживает LiveData из коробки: можно подписаться на LiveData в тесте, изменить состояние через ViewModel и проверить эмитированное значение. Для асинхронных операций используется InstantTaskExecutorRule или runBlocking для корутин. Это избавляет от необходимости мокать архитектурные компоненты.
@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-объекты Robolectric не покрывают нужный класс Android SDK, можно создать кастомный Shadow. Для этого создаётся класс с аннотацией @Implements(ClassName.class) и реализуются нужные методы с @Implementation. Кастомные shadows регистрируются через @Config(shadows = [CustomShadow::class]).
Robolectric поддерживает тестирование ContentProvider через Robolectric.buildContentProvider(). Можно проверить CRUD-операции, query c URI-матчингом и обработку прав доступа. Ресурсы (строки, цвета, размеры) также доступны через RuntimeEnvironment.application.resources, что позволяет тестировать код, зависящий от ресурсов.
Переход с инструментационных тестов на 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-кратным ускорением прогона.
Robolectric требует JDK 11 или выше и совместим с AGP (Android Gradle Plugin) от 7.0 до последней стабильной версии. SDK-менеджер Robolectric автоматически загружает необходимые версии Android API при первом запуске — это однократная операция. Для CI-серверов рекомендуется предварительно загрузить SDK через sdkmanager, чтобы избежать задержек при первом прогоне тестов. Обновление Robolectric до новой версии обычно не требует изменений в коде тестов, только обновление номера зависимости в build.gradle.
Robolectric совместим с популярными mocking-фреймворками: MockK для Kotlin и Mockito для Java. Моки используются для изоляции зависимостей: репозиториев, API-клиентов, SharedPreferences. Главное правило — не мокать классы Android SDK, для этого есть shadow-объекты. Мокайте только слои приложения: UseCase, Repository, DataSource и другие компоненты бизнес-логики. Такая комбинация shadow-объектов и моков даёт максимальную гибкость при минимальных затратах на написание тестов.
Часто задаваемые вопросы
Espresso — это инструментационный фреймворк, запускающийся на эмуляторе или устройстве. Robolectric — это юнит-фреймворк, работающий на JVM. Espresso тестирует реальное поведение, Robolectric — изолированную логику в shadow-среде. Они дополняют друг друга.
Да, Robolectric поддерживает Jetpack Compose начиная с версии 4.8. Тесты Compose-компонентов выполняются с помощью ComposeTestRule, аналогично эмулятору. Однако Compose-тесты на Robolectric не проверяют реальный рендеринг — только логику композиции.
Robolectric поддерживает мультимодульные проекты. Каждый модуль настраивается отдельно с указанием своего манифеста и ресурсов. Для модулей без UI-компонентов достаточно библиотечного модуля без android-плагина. В крупных проектах с десятками модулей Robolectric тесты каждого модуля запускаются параллельно, что даёт дополнительный выигрыш в скорости по сравнению с последовательным прогоном на эмуляторе.
Проблема с ресурсами возникает, если в build.gradle не указан unitTests.includeAndroidResources = true или отсутствует @Config-аннотация с правильным путём к манифесту. Robolectric использует скомпилированные ресурсы из build/intermediates.
Robolectric-тесты отлаживаются как обычные Java/Kotlin-тесты в Android Studio. Доступен breakpoint, step-through debug, инспекция shadow-объектов и их состояния. Логирование включается через -Drobolectric.logging=debug в VM options.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также