web-dev-qa-db-fra.com

Robolectric vs Android Test Framework

Robolectric offre des avantages évidents par rapport à Android Test Framework ? J'ai lu les documents concernant les deux cadres mais pour autant que je puisse voir le seul avantage clair concernant Robolectric , c'est qu'il fonctionne sur JVM plutôt que sur DalvikVM, ce qui le rend plus rapide que Android framework.

Y a-t-il d'autres avantages majeurs qui ressortent?

45
Traxex1909

Mise à jour avril 2015 : outils de construction Gradle et Android Studio prend désormais officiellement en charge les tests unitaires et empêcher Android.jar de lancer une erreur de stub (aucune implémentation réelle). Donc, oui, il est possible d'exécuter des tests sur Java VM, lorsque les stubs sont correctement moqués. C'est un début mais n'est toujours pas comparable avec l'énergie de Robolectric. Il y a aussi une troisième alternative, faites défiler vers le bas de cette réponse.

Maintenant, à propos de Robolectric:

Avantages : voici quelques points sur la façon dont il s'est avéré utile dans les tests unitaires:

  1. Vous n'avez pas besoin d'exécuter un émulateur, vous pouvez donc tester certaines parties non UI du projet sans avoir besoin d'un émulateur ou d'un périphérique. Cela s'applique également à l'exécution de tests sur des serveurs d'intégration/de construction continus, aucune instance d'émulateur n'a besoin d'être lancée.

  2. Avec Android Studio, vous pouvez rapidement exécuter une classe de test particulière, lorsque vous travaillez sur l'implémentation pour satisfaire les cas de test. Vous pouvez déboguer lorsque vous écrivez du code. Il s'agit d'un gain de productivité énorme.

  3. Peut simuler presque toutes les choses liées à Android en tant qu'objets shadow, même SQLite. De plus, chaque objet shadow expose de nombreuses fonctions utiles que leurs homologues normales Android Android n'offrent pas). Avec des équivalents fantômes de Android Object, vous pouvez effectuer une vérification interne ou appeler des méthodes spéciales.

  4. Brille vraiment lors du test de code multithread comme AsyncTask s, Loopers et Handlers etc. Vous pouvez mettre en pause et faire avancer rapidement les threads Loopers, même le thread principal. Excellent pour les tests de rappel basés sur le gestionnaire.

  5. Format JUnit 4 pris en charge. Android tient toujours JUnit 3 la dernière fois que j'ai vérifié.

  6. Peut être combiné avec d'autres outils de test comme Mockito, Espresso, etc.

  7. Prend en charge la création d'une instance d'activité fictiveRobolectric.buildActivity() et son contrôle via ActivityController. La manipulation de fragments/vues fonctionne également sur de telles instances d'activité fictive.

  8. Il existe maintenant modules complémentaires qui couvrent également le multi-dex, le support v4, les services de jeu, les cartes et le client http. Ainsi, il est désormais facile de tester le code en utilisant également ces fonctions de bibliothèque.

Inconvénients : Où je l'ai trouvé pas si bon:

  1. Robolectric excelle dans l'aide aux tests unitaires, mais ne couvre pas toutes les fonctionnalités qu'un véritable appareil ou émulateur peut offrir. Par exemple, capteurs, gps, open-gl, etc., etc.

  2. Vous aurez besoin d'un émulateur ou d'un appareil réel lorsque vous effectuez des tests d'intégration ou d'interface utilisateur, afin que les activités et les services puissent interagir avec l'environnement complet Android (d'autres applications, comme l'utilisation de l'application appareil photo pour obtenir une image pour votre application), pas limité. Ici, vous devrez utiliser le framework de test par défaut car il a également des fonctions pour tester l'interface utilisateur.

  3. Le chargement JNI ne semble pas être pris en charge. Le code avec dépendance native ne peut donc pas être testé.

  4. À partir de maintenant, Robolectric a une dépendance câblée au pot Google Maps pour fonctionner. Et va télécharger un autre Android.jar de maven. Ainsi, la configuration du projet peut nécessiter un peu de bricolage. Mise à jour: à partir de la v3, il semble tirer toutes les dépendances via Gradle sans trop de bruit.

  5. Plus récent Android prennent en charge la couverture et la génération de rapports, etc., mais uniquement lorsque les tests sont exécutés sur un appareil. Donc, avec Robolectric, vous devrez créer des tâches Gradle supplémentaires (exécuter Jaococ) pour le faire pour vous . Mise à jour: Gradle 2.9 + est livré avec le plugin jacoco.

  6. Comme gradle et Android livrent rapidement des versions de construction plus récentes, les versions stables de Robolectric commenceront parfois à avoir des problèmes avec les outils de construction modifiés. La plupart des problèmes typiques incluent: version sdk incompatible, manifeste non trouvé, incompatibilité des chemins de sortie, ressources non chargées, problèmes de configuration, etc. Certains problèmes sont également liés à des bogues dans les outils Android. Parfois, vous devrez peut-être même écrire votre propre test personnalisé runner ou appliquer des solutions de contournement jusqu'à ce que la prochaine version corrige ces problèmes. Consultez problèmes ouverts et configurez les tests en conséquence.


Une autre alternative est simplement de se moquer de soi, sans aucun cadre. C'est la "voie difficile" mais la manière la plus personnalisable. Son JUnit simple avec JMockit :

@RunWith(JMockit.class)
public class OtherTest {
    public void testHandlerCallback(@Mocked final FragmentTransaction transaction,
                                    @Mocked final FragmentManager manager,
                                    @Mocked final Activity activity,
                                    @Mocked final LayoutInflater inflater,
                                    @Mocked final ViewGroup parent) {

        final List<Fragment> fragments = new ArrayList<>();
        new Expectations() {{
            activity.getFragmentManager(); result = manager;
            manager.beginTransaction(); result = transaction;
            transaction.add(withCapture(fragments), anyString);
            transaction.commit(); result = new Delegate<Void>() {
                public int commit() {
                    View v = fragments.get(0).onCreateView(inflater,parent,null);
                    Deencapsulation.invoke(v,"onMeasure",0,0);
                  return  0;  
                }
            };
        }};
    }
}

Ci-dessus est un exemple brut et en ligne. Vous pouvez réellement créer des classes réutilisables appropriées (disons FragmentTestHarness) qui prendront un composant (disons un Fragment) sous test et l'envelopperont dans un environnement complètement isolé, le préparant pour les tests.

77
S.D.

Pour partager comment je fais ...

Robolectric Pour SQL, les activités s'écoulent, pour les objets qui avaient besoin de contexte.

JUnit4 pour les API Java pour s'assurer que les données sont retournées correctement.

Espresso Pour vérifier correctement l'affichage de l'interface utilisateur.

Quand j'ai modifié l'api ... je lance seulement jUnit4.

Lorsque j'ai modifié la liaison de données entre l'API et l'interface utilisateur ou Sqlite, je n'exécuterai que Robolectric.

Lorsque j'ai modifié l'interface utilisateur, je lance uniquement Espresso.

Parfois, je vais faire fonctionner Robolectric et expresso ensemble, mais c'est très rare.

Mais je vais tout exécuter avant de publier sur Play Store.

Parce que je pense qu'il n'y a pas de réel avantage pour l'instant. Mais voyez comment vous l'utilisez pour accélérer la qualité de votre produit et la vitesse de développement.

Corrigez-moi si je me trompe.

25
Shawn Thye

Le principal avantage de Robolectric est la vitesse. Les tests unitaires avec Robolectric ne nécessitent pas d'émulateur ou d'appareil en cours d'exécution pour exécuter les tests et sont donc beaucoup plus rapides.

Vous voudrez peut-être toujours avoir une suite de tests d'intégration qui s'exécutent sur un appareil réel, juste une suite beaucoup plus petite.

3
koljaTM

Vous utiliseriez Robolectric uniquement dans les cas où vous devez vous moquer ou simuler le framework Android , par exemple si vous avez besoin d'un contexte. Lorsque vous utilisez le Android Test Framework , vous devrez exécuter des tests instrumentés pour ce qui est ultra lent.

Si vous écrivez vos tests pour les laisser s'exécuter fréquemment, par ex. parce que vous suivez une approche tdd, ce n'est pas une option. Donc dans ce cas Robolectric est très pratique.

Ainsi, le principal avantage de Robolectric est qu'il est beaucoup plus rapide que Espresso ou Tests instrumentés en général.

L'inconvénient est qu'il simule un environnement Android dont vous devriez être conscient. Pour valider les problèmes du monde réel, mieux vaut utiliser une approche classique Android Framework).

Le mieux est encore d'écrire votre code de manière à ce que vous puissiez le tester à l'unité et que vous n'ayez pas besoin d'un contexte ou de tout autre Android dépendances du framework .

Robolectric s'intègre dans le Android Framework de test depuis les E/S 2018 - découvrez plus sur le page Robolectric officielle et regardez cette vidéo de I/O 2018

1
luckyhandler