Robolectric — qu'est-ce que c'est, principes de fonctionnement et tests unitaires Android

Auteur : IT Sectr Publié le : 2026-04-09 Temps de lecture : 8 min

Robolectric est un framework de tests unitaires pour applications Android qui permet d'exécuter des tests directement sur la JVM sans émulateur ni périphérique physique. Il intercepte les appels de l'Android SDK et fournit des shadow-objects qui imitent le comportement des composants réels. Selon Robolectric Documentation, 2025, les shadow-objects remplacent environ 15 000 classes de l'API Android, assurant l'isolement des tests de la plateforme.

Points clés

  • Robolectric — framework de tests unitaires Android sans émulateur, fonctionnant sur la JVM
  • Shadow-objects interceptent les appels de l'Android SDK et imitent le comportement du système
  • Intégration avec JUnit 4 et 5 permet d'utiliser des exécuteurs de tests standard
  • Les tests s'exécutent en secondes, pas en minutes comme dans l'émulateur
  • Prise en charge de Jetpack Compose, fragments, intents, ContentProvider et ressources

Qu'est-ce que Robolectric

Robolectric est un framework open source créé en 2010 pour accélérer les tests d'applications Android. Au lieu de s'exécuter sur un émulateur ou un appareil, Robolectric fournit des implémentations shadow des classes de l'Android SDK qui fonctionnent directement sur la Machine Virtuelle Java (JVM). Cela permet d'exécuter des milliers de tests en quelques secondes.

Le problème résolu par Robolectric

Les tests Android traditionnels nécessitent l'exécution de l'application sur un émulateur, ce qui prend 3 à 10 minutes pour compiler l'APK, l'installer et le lancer. Robolectric élimine cette étape : les tests sont compilés comme des tests Java/Kotlin normaux et exécutés via JUnit. Cela offre une boucle de rétroaction de quelques secondes au lieu de minutes.

Versions d'Android prises en charge

Robolectric prend en charge toutes les versions d'Android de l'API 16 (Android 4.1) jusqu'à la dernière version stable. Pour chaque version, un ensemble correspondant de shadow-objects est fourni, imitant le comportement de la version spécifique de la plateforme sur laquelle l'application est testée.

Architecture et shadow-objects

L'architecture de Robolectric est basée sur l'interception d'appels via le remplacement du chargeur de classes. Lorsqu'un test appelle une méthode de l'Android SDK, Robolectric intercepte l'appel et le dirige vers un shadow-object. Un shadow-object est une classe Java qui imite le comportement réel d'un composant Android mais fonctionne sans la plateforme native.

Comment fonctionnent les shadows

Les shadow-objects implémentent les méthodes clés des classes Android d'origine. Par exemple, ShadowTextView imite des méthodes comme getText(), setText(), getCurrentTextColor() et d'autres. Lorsque textView.setText("Bonjour") est appelé, le shadow enregistre la chaîne et la retourne lors de l'appel de getText(). Cela isole les tests du rendu réel et des services système.

Hiérarchie des shadows

Robolectric prend en charge plus de 200 classes shadow couvrant les principaux composants de l'Android SDK : Activity, Fragment, TextView, Button, RecyclerView, WebView, LocationManager, ConnectivityManager et bien d'autres. Les shadow-objects suivent la même hiérarchie d'héritage que les classes Android d'origine.

Installation et configuration de Robolectric

L'installation de Robolectric dans un projet Gradle nécessite d'ajouter la dépendance testImplementation "org.robolectric:robolectric:4.x". Il faut également spécifier la configuration androidsdk dans le fichier build.gradle et ajouter la résolution android:testInstrumentationRunner. Aucun plugin de test Android n'est nécessaire pour travailler avec Robolectric.

Configuration de base de Gradle

Après avoir ajouté la dépendance, il faut configurer le répertoire pour le manifeste, les ressources et les assets. Robolectric trouve automatiquement AndroidManifest.xml, mais il peut être nécessaire de spécifier le chemin manuellement via l'annotation @Config ou les propriétés système. Pour les projets multi-modules, la configuration est définie séparément pour chaque module.

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

L'annotation @Config

L'annotation @Config permet de remplacer les paramètres de test : sdk (version de l'API), manifest (chemin vers le manifeste), qualifiers (configuration de l'écran, langue). Ceci est utile pour tester le comportement de l'application sur différentes versions d'Android, orientations d'écran et localisations.

Écrire des tests avec Robolectric

Les tests Robolectric s'écrivent comme des tests unitaires classiques avec @RunWith(RobolectricTestRunner.class) pour JUnit 4 ou via RobolectricExtension pour JUnit 5. ActivityController gère le cycle de vie de l'Activity : create(), start(), resume(), pause(), stop(), destroy(). Cela permet de tester en détail chaque transition d'état.

Tester une Activity

Pour tester une Activity, on utilise ActivityController qui parcourt séquentiellement les étapes du cycle de vie. L'accès à l'Activity se fait via controller.get(). Tous les composants de vue sont accessibles via findViewById, comme dans une application réelle. Les shadow-objects permettent de vérifier les textes, la visibilité, les couleurs et d'autres attributs des vues.

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

Tester les intents et la navigation

Robolectric intercepte les appels startActivity() et permet de vérifier les intents envoyés via ShadowActivity. Cela permet de tester la navigation : vérifier qu'en cliquant sur un bouton, un Intent est envoyé avec les bons paramètres Action, Data et 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 vs émulateur

Robolectric et l'émulateur résolvent des tâches différentes. Robolectric est idéal pour les tests unitaires rapides, la vérification de la logique d'interface utilisateur, des composants métier et des dépôts. L'émulateur est nécessaire pour les tests d'instrumentation, la vérification d'intégration avec les API, les tests de caméra, de capteurs et de performance.

CaractéristiqueRobolectricÉmulateur
Vitesse~5 s pour 100 tests~5 min pour 100 tests
LancementSans compilation d'APKNécessite compilation d'APK
API réelleShadow-émulationAndroid SDK natif
Prêt à l'emploiJUnit uniquementTout framework

Tester ViewModel et Repository

Robolectric est excellent pour tester ViewModel, Repository et UseCase — des composants qui utilisent l'Android SDK mais ne nécessitent pas d'interface utilisateur réelle. Le ViewModel est testé via un test JUnit classique avec RobolectricExtension, tandis que les composants de cycle de vie (LiveData, StateFlow) fonctionnent dans l'environnement shadow sans mocks.

Tester LiveData

Robolectric prend en charge LiveData directement : vous pouvez vous abonner à LiveData dans le test, modifier l'état via ViewModel et vérifier la valeur émise. Pour les opérations asynchrones, on utilise InstantTaskExecutorRule ou runBlocking pour les coroutines. Cela élimine le besoin de simuler les composants architecturaux.

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-objects personnalisés

Si les shadow-objects standard de Robolectric ne couvrent pas une classe nécessaire de l'Android SDK, vous pouvez créer un Shadow personnalisé. Pour cela, créez une classe avec l'annotation @Implements(ClassName.class) et implémentez les méthodes nécessaires avec @Implementation. Les shadows personnalisés sont enregistrés via @Config(shadows = [CustomShadow::class]).

Tester ContentProvider et Resources

Robolectric prend en charge les tests de ContentProvider via Robolectric.buildContentProvider(). Vous pouvez vérifier les opérations CRUD, les requêtes avec correspondance d'URI et la gestion des droits d'accès. Les ressources (chaînes, couleurs, dimensions) sont également accessibles via RuntimeEnvironment.application.resources, permettant de tester le code dépendant des ressources.

Migration de l'émulateur vers Robolectric

La transition des tests d'instrumentation vers Robolectric nécessite un changement d'approche. Les tests d'instrumentation (AndroidJUnit4) vérifient le comportement réel sur l'émulateur, tandis que Robolectric vérifie la logique isolée dans un environnement shadow. Il est recommandé de couvrir la logique métier avec des tests Robolectric et de laisser les tests d'instrumentation pour les scénarios d'intégration.

Adaptation des tests existants

Lors de la migration, il faut : remplacer AndroidJUnit4 par RobolectricTestRunner, ajouter @Config avec la version SDK cible, remplacer ActivityTestRule par ActivityController et déplacer les dépendances de androidTestImplementation vers testImplementation. Les mocks (MockK, Mockito) fonctionnent avec Robolectric sans modification — ils sont indépendants de la plateforme.

Limitations de la migration

Robolectric ne prend pas en charge : les tests de caméra (CameraX), NFC, Bluetooth, la biométrie, le travail avec des fichiers réels et les bibliothèques natives. Ces scénarios nécessitent des tests d'instrumentation sur l'émulateur. Robolectric ne reproduit pas non plus le rendu réel — les tests de mise en page sont mieux réalisés via Compose Test Rule ou Espresso. Cependant, pour vérifier la logique métier, la navigation et les états ViewModel, Robolectric remplace complètement l'émulateur avec une accélération de 10x.

Compatibilité avec les versions Java et Kotlin

Robolectric nécessite JDK 11 ou supérieur et est compatible avec AGP (Android Gradle Plugin) de 7.0 à la dernière version stable. Le SDK Manager de Robolectric télécharge automatiquement les versions d'API Android nécessaires au premier lancement — c'est une opération unique. Pour les serveurs CI, il est recommandé de précharger le SDK via sdkmanager pour éviter les délais lors du premier lancement des tests. La mise à jour de Robolectric vers une nouvelle version ne nécessite généralement pas de modifications du code de test, seulement la mise à jour du numéro de dépendance dans build.gradle.

Intégration avec MockK et Mockito

Robolectric est compatible avec les frameworks de simulation populaires : MockK pour Kotlin et Mockito pour Java. Les mocks sont utilisés pour isoler les dépendances : dépôts, clients API, SharedPreferences. La règle principale est de ne pas simuler les classes de l'Android SDK — pour cela, il existe des shadow-objects. Simulez uniquement les couches applicatives : UseCase, Repository, DataSource et autres composants de logique métier. Cette combinaison de shadow-objects et de mocks offre une flexibilité maximale avec un effort minimal de rédaction de tests.

Foire aux questions

Quelle est la différence entre Robolectric et Espresso ?

Espresso est un framework d'instrumentation qui s'exécute sur un émulateur ou un appareil. Robolectric est un framework de tests unitaires qui fonctionne sur la JVM. Espresso teste le comportement réel, Robolectric teste la logique isolée dans un environnement shadow. Ils se complètent mutuellement.

Peut-on tester Jetpack Compose avec Robolectric ?

Oui, Robolectric prend en charge Jetpack Compose à partir de la version 4.8. Les tests de composants Compose sont exécutés avec ComposeTestRule, similairement à l'émulateur. Cependant, les tests Compose sur Robolectric ne vérifient pas le rendu réel — seulement la logique de composition.

Comment Robolectric fonctionne-t-il avec les modules Gradle ?

Robolectric prend en charge les projets multi-modules. Chaque module est configuré séparément avec son propre manifeste et ses ressources. Pour les modules sans composants d'interface utilisateur, un module de bibliothèque sans plugin Android suffit. Dans les grands projets avec des dizaines de modules, les tests Robolectric de chaque module s'exécutent en parallèle, offrant un gain de vitesse supplémentaire par rapport à l'exécution séquentielle sur l'émulateur.

Pourquoi Robolectric pourrait-il ne pas trouver les ressources ?

Le problème de ressources survient si dans le build.gradle unitTests.includeAndroidResources = true n'est pas défini ou si l'annotation @Config avec le chemin correct vers le manifeste est absente. Robolectric utilise les ressources compilées de build/intermediates.

Comment déboguer les tests Robolectric ?

Les tests Robolectric se déboguent comme des tests Java/Kotlin normaux dans Android Studio. Les points d'arrêt, le débogage pas à pas et l'inspection des shadow-objects et de leur état sont disponibles. La journalisation est activée via -Drobolectric.logging=debug dans les options de la machine virtuelle.

Résumé

  • Robolectric — framework de tests unitaires rapides Android sur la JVM sans émulateur
  • Shadow-objects remplacent plus de 200 classes de l'Android SDK, imitant leur comportement
  • Cycle de vie d'Activity et Fragment est géré via ActivityController avec vérification d'état
  • Tests d'intents via ShadowActivity permettent de vérifier la navigation et le transfert de données
  • Intégration avec JUnit et Gradle ne nécessite pas d'exécuteurs d'instrumentation supplémentaires
  • L'annotation @Config spécifie la version de l'API, la langue, la configuration d'écran et les ressources
  • Robolectric et Espresso se complètent : tests unitaires rapides vs instrumentation

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi