Το Robolectric είναι ένα framework για unit testing εφαρμογών Android που επιτρέπει την εκτέλεση tests απευθείας στο JVM χωρίς εξομοιωτή ή φυσική συσκευή. Παρεμποδίζει κλήσεις του Android SDK και παρέχει shadow-αντικείμενα που εξομοιώνουν τη συμπεριφορά πραγματικών στοιχείων. Σύμφωνα με το Robolectric Documentation, 2025, τα shadow-αντικείμενα αντικαθιστούν περίπου 15 χιλιάδες κλάσεις Android API, εξασφαλίζοντας απομόνωση των tests από την πλατφόρμα.
Κύρια Σημεία
Robolectric είναι ένα open-source framework, που δημιουργήθηκε το 2010 για την επιτάχυνση του testing εφαρμογών Android. Αντί να εκτελείται σε εξομοιωτή ή συσκευή, το Robolectric παρέχει shadow-υλοποιήσεις κλάσεων Android SDK που λειτουργούν απευθείας στην Java Virtual Machine (JVM). Αυτό επιτρέπει την εκτέλεση χιλιάδων tests σε δευτερόλεπτα.
Το παραδοσιακό Android testing απαιτεί εκτέλεση της εφαρμογής σε εξομοιωτή, που διαρκεί 3–10 λεπτά για τη δημιουργία APK, εγκατάσταση και εκκίνηση. Το Robolectric εξαλείφει αυτό το βήμα: τα tests μεταγλωττίζονται ως συνηθισμένα Java/Kotlin tests και εκτελούνται μέσω JUnit. Αυτό δίνει έναν κύκλο ανάδρασης λίγων δευτερολέπτων αντί για λεπτά.
Το Robolectric υποστηρίζει όλες τις εκδόσεις Android από API 16 (Android 4.1) έως την τελευταία σταθερή έκδοση. Για κάθε έκδοση παρέχεται ένα αντίστοιχο σύνολο shadow-αντικειμένων που εξομοιώνουν τη συμπεριφορά ακριβώς εκείνης της έκδοσης πλατφόρμας στην οποία δοκιμάζεται η εφαρμογή.
Η αρχιτεκτονική του Robolectric βασίζεται στον μηχανισμό παρεμπόδισης κλήσεων μέσω αντικατάστασης του classloader. Όταν ένα test καλεί μια μέθοδο του Android SDK, το Robolectric παρεμποδίζει την κλήση και την κατευθύνει στο shadow-αντικείμενο. Shadow-αντικείμενο είναι μια κλάση Java που μιμείται την πραγματική συμπεριφορά ενός στοιχείου Android, αλλά λειτουργεί χωρίς native πλατφόρμα.
Τα shadow-αντικείμενα υλοποιούν βασικές μεθόδους των αρχικών κλάσεων Android. Για παράδειγμα, το ShadowTextView μιμείται τις μεθόδους getText(), setText(), getCurrentTextColor() και άλλες. Κατά την κλήση textView.setText(“Hello”) το shadow αποθηκεύει το string και το επιστρέφει κατά την κλήση getText(). Αυτό απομονώνει τα tests από την πραγματική απόδοση και τις υπηρεσίες συστήματος.
Το Robolectric υποστηρίζει πάνω από 200 shadow-κλάσεις που καλύπτουν τα κύρια στοιχεία του Android SDK: Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager και πολλά άλλα. Τα shadow-αντικείμενα ακολουθούν την ίδια ιεραρχία κληρονομικότητας με τις αρχικές κλάσεις Android.
Η εγκατάσταση του Robolectric σε ένα έργο Gradle απαιτεί την προσθήκη της εξάρτησης testImplementation “org.robolectric:robolectric:4.x”. Επίσης, πρέπει να καθοριστεί η ρύθμιση android:sdk στο αρχείο build.gradle και να προστεθεί το android:testInstrumentationRunner. Για τη λειτουργία με Robolectric δεν απαιτείται το πρόσθετο android-test.
Μετά την προσθήκη της εξάρτησης, πρέπει να ρυθμιστεί ο κατάλογος για το manifest, τους πόρους και τα assets. Το 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 σχολιασμός επιτρέπει την παράκαμψη παραμέτρων test: sdk (έκδοση API), manifest (διαδρομή προς το manifest), qualifiers (ρύθμιση οθόνης, γλώσσα). Αυτό είναι χρήσιμο για τη δοκιμή συμπεριφοράς της εφαρμογής σε διαφορετικές εκδόσεις Android, προσανατολισμούς οθόνης και τοπικές ρυθμίσεις.
Τα Robolectric tests γράφονται ως συνηθισμένα unit tests με @RunWith(RobolectricTestRunner.class) για JUnit 4 ή μέσω RobolectricExtension για JUnit 5. ActivityController διαχειρίζεται τον κύκλο ζωής Activity: create(), start(), resume(), pause(), stop(), destroy(). Αυτό επιτρέπει λεπτομερή δοκιμή κάθε μετάβασης κατάστασης.
Για τη δοκιμή Activity χρησιμοποιείται το ActivityController που διέρχεται διαδοχικά από τα στάδια του κύκλου ζωής. Η πρόσβαση στο Activity γίνεται μέσω controller.get(). Όλα τα στοιχεία προβολής είναι προσβάσιμα μέσω 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() και επιτρέπει τον έλεγχο των σταλμένων intent μέσω 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 είναι ιδανικό για γρήγορα unit tests, έλεγχο λογικής UI, επιχειρηματικών στοιχείων και αποθετηρίων. Ο εξομοιωτής είναι απαραίτητος για instrumental tests, έλεγχο ενσωμάτωσης με API, δοκιμή κάμερας, αισθητήρων και απόδοσης.
| Χαρακτηριστικό | Robolectric | Εξομοιωτής |
|---|---|---|
| Ταχύτητα | ~5 δευτ. ανά 100 tests | ~5 λεπ. ανά 100 tests |
| Εκκίνηση | Χωρίς δημιουργία APK | Απαιτεί δημιουργία APK |
| Πραγματικό API | Shadow-εξομοίωση | Native Android SDK |
| Out-of-the-box | Μόνο JUnit | Οποιαδήποτε frameworks |
Το Robolectric είναι εξαιρετικό για δοκιμή ViewModel, Repository και UseCase — στοιχεία που χρησιμοποιούν Android SDK αλλά δεν απαιτούν πραγματικό UI. ViewModel δοκιμάζεται μέσω συνηθισμένου JUnit test με RobolectricExtension, ενώ τα στοιχεία κύκλου ζωής (LiveData, StateFlow) λειτουργούν σε shadow-περιβάλλον χωρίς mock.
Το Robolectric υποστηρίζει LiveData out of the box: μπορεί κανείς να εγγραφεί στο LiveData στο test, να αλλάξει κατάσταση μέσω ViewModel και να ελέγξει την εκπεμπόμενη τιμή. Για ασύγχρονες λειτουργίες χρησιμοποιείται InstantTaskExecutorRule ή runBlocking για coroutines. Αυτό εξαλείφει την ανάγκη δημιουργίας mock για αρχιτεκτονικά στοιχεία.
@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 με αντιστοίχιση URI και διαχείριση δικαιωμάτων πρόσβασης. Οι πόροι (strings, χρώματα, μεγέθη) είναι επίσης προσβάσιμοι μέσω RuntimeEnvironment.application.resources, επιτρέποντας τη δοκιμή κώδικα που εξαρτάται από πόρους.
Η μετάβαση από instrumental tests σε Robolectric απαιτεί αλλαγή προσέγγισης. Instrumental tests (AndroidJUnit4) ελέγχουν πραγματική συμπεριφορά στον εξομοιωτή, Robolectric — απομονωμένη λογική σε shadow-περιβάλλον. Συνιστάται η κάλυψη επιχειρηματικής λογικής με Robolectric tests, και τα instrumental tests να διατηρούνται για σενάρια ενσωμάτωσης.
Κατά τη μετάβαση πρέπει: αντικατάσταση AndroidJUnit4 με RobolectricTestRunner, προσθήκη @Config με την έκδοση SDK-στόχο, αντικατάσταση ActivityTestRule με ActivityController, και μεταφορά εξαρτήσεων από androidTestImplementation σε testImplementation. Τα Mock (MockK, Mockito) λειτουργούν με Robolectric χωρίς αλλαγές — δεν εξαρτώνται από την πλατφόρμα.
Το Robolectric δεν υποστηρίζει: δοκιμή κάμερας (CameraX), NFC, Bluetooth, βιομετρικών, εργασία με πραγματικά αρχεία και native βιβλιοθήκες. Γι’ αυτά τα σενάρια απαιτούνται instrumental tests στον εξομοιωτή. Το Robolectric επίσης δεν αναπαράγει πραγματική απόδοση — τα tests διάταξης είναι καλύτερο να εκτελούνται μέσω Compose Test Rule ή Espresso. Ωστόσο, για έλεγχο επιχειρηματικής λογικής, πλοήγησης και καταστάσεων ViewModel, το Robolectric αντικαθιστά πλήρως τον εξομοιωτή με 10πλάσια επιτάχυνση.
Το Robolectric απαιτεί JDK 11 ή νεότερο και είναι συμβατό με AGP (Android Gradle Plugin) από 7.0 έως την τελευταία σταθερή έκδοση. SDK manager του Robolectric κατεβάζει αυτόματα τις απαραίτητες εκδόσεις Android API κατά την πρώτη εκκίνηση — αυτή είναι μια εφάπαξ λειτουργία. Για διακομιστές CI συνιστάται προηγούμενη λήψη του SDK μέσω sdkmanager για αποφυγή καθυστερήσεων κατά την πρώτη εκτέλεση tests. Η ενημέρωση του Robolectric σε νέα έκδοση συνήθως δεν απαιτεί αλλαγές στον κώδικα tests, μόνο ενημέρωση του αριθμού εξάρτησης στο build.gradle.
Το Robolectric είναι συμβατό με δημοφιλή mocking frameworks: MockK για Kotlin και Mockito για Java. Τα Mock χρησιμοποιούνται για απομόνωση εξαρτήσεων: αποθετήρια, API clients, SharedPreferences. Βασικός κανόνας — μην κάνετε mock κλάσεις Android SDK, γι’ αυτό υπάρχουν shadow-αντικείμενα. Κάνετε mock μόνο επίπεδα εφαρμογής: UseCase, Repository, DataSource και άλλα στοιχεία επιχειρηματικής λογικής. Τέτοιος συνδυασμός shadow-αντικειμένων και mock δίνει μέγιστη ευελιξία με ελάχιστο κόστος σύνταξης tests.
Συχνές Ερωτήσεις
Το Espresso είναι ένα instrumental framework που εκτελείται σε εξομοιωτή ή συσκευή. Το Robolectric είναι ένα unit framework που λειτουργεί στο JVM. Το Espresso δοκιμάζει πραγματική συμπεριφορά, το Robolectric — απομονωμένη λογική σε shadow-περιβάλλον. Αλληλοσυμπληρώνονται.
Ναι, το Robolectric υποστηρίζει Jetpack Compose από την έκδοση 4.8. Τα tests στοιχείων Compose εκτελούνται με ComposeTestRule, παρόμοια με τον εξομοιωτή. Ωστόσο, τα Compose tests στο Robolectric δεν ελέγχουν πραγματική απόδοση — μόνο λογική σύνθεσης.
Το Robolectric υποστηρίζει πολυαρθρωτά έργα. Κάθε άρθρωμα ρυθμίζεται ξεχωριστά με καθορισμό του δικού του manifest και πόρων. Για αρθρώματα χωρίς στοιχεία UI, αρκεί ένα άρθρωμα βιβλιοθήκης χωρίς το πρόσθετο android. Σε μεγάλα έργα με δεκάδες αρθρώματα, τα Robolectric tests κάθε αρθρώματος εκτελούνται παράλληλα, δίνοντας πρόσθετο πλεονέκτημα ταχύτητας σε σύγκριση με σειριακή εκτέλεση στον εξομοιωτή.
Το πρόβλημα με πόρους προκύπτει αν στο build.gradle δεν έχει καθοριστεί unitTests.includeAndroidResources = true ή λείπει ο @Config σχολιασμός με σωστή διαδρομή προς το manifest. Το Robolectric χρησιμοποιεί μεταγλωττισμένους πόρους από το build/intermediates.
Τα Robolectric tests γίνονται debug όπως συνηθισμένα Java/Kotlin tests στο Android Studio. Διατίθενται breakpoint, step-through debug, επιθεώρηση shadow-αντικειμένων και κατάστασής τους. Η καταγραφή ενεργοποιείται μέσω -Drobolectric.logging=debug στις επιλογές VM.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης