Comment testez-vous une application Android sur plusieurs activités?

Nous construisons une application Android complexe composée de nombreux écrans et workflows répartis sur de nombreuses activités. Nos stream de travail sont similaires à ce que vous pouvez voir sur un guichet automatique bancaire. Par exemple, il existe une Activity permettant de se connecter à un menu principal. Activity pouvant faire la transition vers d’autres activités en fonction des choix de l’utilisateur.

Comme nous avons tellement de workflows, nous devons créer des tests automatisés couvrant plusieurs activités afin de pouvoir tester un workflow de bout en bout. Par exemple, en utilisant l’exemple ATM, nous voudrions entrer un code PIN valide, vérifier que cela nous envoie au menu principal, choisir de retirer de l’argent, vérifier que nous sums sur l’écran de retrait, etc., etc. Retour sur le menu principal ou “connecté”.

Nous avons joué avec les API de test fournies avec Android (par exemple ActivityInstrumentationTestCase2 ) et avec Positron , mais aucune ne semble capable de tester au-delà des limites d’une seule Activity , et bien que nous puissions trouver des utilitaires pour certains tests unitaires, ils ne répondront pas à nos besoins en matière de scénarios de test couvrant plusieurs activités.

Nous sums ouverts à un framework xUnit, à des scripts, à des enregistreurs / lectures d’interface graphique, etc. et souhaiterions recevoir des conseils.

Je me sens un peu gêné de répondre à ma propre question sur les primes, mais la voici …

J’ai cherché haut et bas là-dessus et je ne peux pas croire qu’il n’y a pas de réponse publiée nulle part. Je suis venu très près. Je peux certainement exécuter des tests qui couvrent des activités maintenant, mais mon implémentation semble présenter des problèmes de synchronisation où les tests ne sont pas toujours fiables. C’est le seul exemple que je connaisse qui teste avec succès plusieurs activités. J’espère que mon extraction et anonymisation de celui-ci n’a pas introduit d’erreurs. Il s’agit d’un test simpliste dans lequel je saisis un nom d’utilisateur et un mot de passe dans une activité de connexion, puis observe un message de bienvenue approprié dans une autre activité «bienvenue»:

 package com.mycompany; import android.app.*; import android.content.*; import android.test.*; import android.test.suitebuilder.annotation.*; import android.util.*; import android.view.*; import android.widget.*; import static org.hamcrest.core.Is.*; import static org.hamcrest.core.IsNull.*; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.junit.Assert.*; import static com.mycompany.R.id.*; public class LoginTests extends InstrumentationTestCase { @MediumTest public void testAValidUserCanLogIn() { Instrumentation instrumentation = getInstrumentation(); // Register we are interestd in the authentication activiry... Instrumentation.ActivityMonitor monitor = instrumentation.addMonitor(AuthenticateActivity.class.getName(), null, false); // Start the authentication activity as the first activity... Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClassName(instrumentation.getTargetContext(), AuthenticateActivity.class.getName()); instrumentation.startActivitySync(intent); // Wait for it to start... Activity currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); assertThat(currentActivity, is(notNullValue())); // Type into the username field... View currentView = currentActivity.findViewById(username_field); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(EditText.class)); TouchUtils.clickView(this, currentView); instrumentation.sendSsortingngSync("MyUsername"); // Type into the password field... currentView = currentActivity.findViewById(password_field); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(EditText.class)); TouchUtils.clickView(this, currentView); instrumentation.sendSsortingngSync("MyPassword"); // Register we are interestd in the welcome activity... // this has to be done before we do something that will send us to that // activity... instrumentation.removeMonitor(monitor); monitor = instrumentation.addMonitor(WelcomeActivity.class.getName(), null, false); // Click the login button... currentView = currentActivity.findViewById(login_button; assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(Button.class)); TouchUtils.clickView(this, currentView); // Wait for the welcome page to start... currentActivity = getInstrumentation().waitForMonitorWithTimeout(monitor, 5); assertThat(currentActivity, is(notNullValue())); // Make sure we are logged in... currentView = currentActivity.findViewById(welcome_message); assertThat(currentView, is(notNullValue())); assertThat(currentView, instanceOf(TextView.class)); assertThat(((TextView)currentView).getText().toSsortingng(), is("Welcome, MyUsername!")); } } 

Ce code n’est évidemment pas très lisible. Je l’ai en fait extrait dans une bibliothèque simple avec une API de type anglais, pour que je puisse dire des choses comme ceci:

 type("myUsername").intoThe(username_field); click(login_button); 

J’ai testé jusqu’à 4 activités en profondeur et je suis convaincu que l’approche fonctionne bien que, comme je l’ai dit, il semble y avoir un problème de synchronisation occasionnel que je n’ai pas complètement compris. Je suis toujours intéressé par d’autres moyens de tester les différentes activités.

Jetez un oeil à Robotium
«une infrastructure de test open-source créée pour rendre les tests automatiques des applications Android beaucoup plus rapides et plus faciles que ce qui est possible avec les tests d’instrumentation Android prêts à l’emploi.

Page d’accueil: http://www.robotium.org/
Source: http://github.com/jayway/robotium

Veuillez noter que le projet Robotium est maintenu par la société pour laquelle je travaille.

Vous pouvez toujours utiliser Robotium. Il supporte les tests de blackbox tout comme Selenium mais pour Android. Vous le trouverez sur Robotium.org

Je suis surpris que personne n’ait mentionné certains des principaux outils automatisés de test fonctionnel . Par rapport à Robotium, il n’est pas nécessaire d’écrire du code Java.

MonkeyTalk : un outil open-source soutenu par la société Gorilla Logic. Avantages: fournit un enregistrement et un langage de script de niveau supérieur plus facile pour les utilisateurs non techniques, et est multi-plateforme (y compris iOS). Compte tenu de ces avantages en tant qu’exigences, nous avons trouvé que c’était la meilleure solution. Il permet également la personnalisation au-delà de ce qui peut être fait dans leur langage de script en utilisant Javascript.

Calabash-Android : un outil open-source pour les fonctionnalités de type concombre. Avantages: écrire des fonctionnalités dans le langage Gherkin, qui est lisible par Business, Langage spécifique au domaine, qui vous permet de décrire le comportement du logiciel sans détailler la manière dont ce comportement est implémenté. Un support similaire mais non exact est disponible pour iOS dans cucumber-ios . Les capacités d’enregistrement ne sont pas aussi bonnes, car elles produisent une sortie binary.

Quelques autres références:

  • Voici quelques comparaisons supplémentaires entre Robotium, Monkeytalk et Calabash. Il mentionne TestDroid comme une autre possibilité.
  • Ce blog mentionne ce qui précède, plus NativeDriver et Bot-bot.

J’ai créé un outil d’enregistrement et de lecture pour Android et l’a rendu disponible sur GitHub . Il est facile à configurer et à utiliser, ne nécessite aucune programmation, fonctionne sur des périphériques réels (qui ne doivent pas nécessairement être enracinés) et enregistre automatiquement les captures d’écran pendant la lecture des tests.

Tout d’abord, utilisez “ActivityInstrumentationTestCase2” et non “InstrumentationTestCase” comme classe de base. J’utilise Robotium et teste régulièrement plusieurs activités. J’ai trouvé que je devais spécifier l’activité de connexion comme type générique (et argument de classe pour le constructeur).

Le constructeur ‘ActivityInstrumentationTestCase2’ ignore l’argument du package et ne le requirejs pas. Le constructeur qui prend le paquet est déconseillé.

Dans Javadocs: “ActivityInstrumentationTestCase2 (Ssortingng pkg, Class activityClass) Ce constructeur est obsolète. Utilisez plutôt ActivityInstrumentationTestCase2 (Class)”

L’utilisation de la classe de base recommandée permet au framework de gérer certaines procédures standard, comme le démarrage de votre activité. Cela est fait par l’appel à ‘getActivity ()’, si nécessaire.

Cela a été utile avec quelques modifications. Premièrement getInstrumentation().waitForIdleSync() résoudra le problème dont parle SingleShot et InstrumentationTestCase a également une fonction lauchActivity qui peut remplacer les lignes d’activité de début.

Vous pouvez le faire comme ça pour éviter que les délais d’attente ne soient pas synchronisés:

 final Button btnLogin = (Button) getActivity().findViewById(R.id.button); Instrumentation instrumentation = getInstrumentation(); // Register we are interestd in the authentication activity... Instrumentation.ActivityMonitor aMonitor = instrumentation.addMonitor(mynextActivity.class.getName(), null, false); getInstrumentation().runOnMainSync(new Runnable() { public void run() { btnLogin.performClick(); } }); getInstrumentation().waitForIdleSync(); //check if we got at least one hit on the new activity assertTrue(getInstrumentation().checkMonitorHit(aMonitor, 1)); 

Je travaille à peu près la même chose, et je vais probablement suivre une variante de la réponse acceptée à cette question, mais je suis tombé sur Calculuon ( gitHub ) lors de mes recherches de solution.

Je ne l’ai pas personnellement utilisé, mais ApplicationTestCase semble être ce que vous cherchez.

L’approche acceptée fonctionnera-t-elle avec différentes activités provenant de différentes applications, signées par différents certificates? Sinon, Robotium est le meilleur moyen de tester les activités dans la même application.

Il y a une autre façon de faire l’activité multiple en utilisant ActivityInstrumentation Class .. C’est un scénario d’automatisation normal … Commencez par vous concentrer sur l’object que vous voulez, puis envoyez une clé Simple comme cet exemple de code

 button.requestFocus(); sendKeys(KeyEvent.KEYCODE_ENTER); 

La seule chose est de comprendre que chaque appel d’API nous aidera.

Cette réponse est basée sur la réponse acceptée mais modifiée pour résoudre le problème de synchronisation qui, pour moi, est devenu cohérent après l’ajout d’une demi-douzaine de tests. @ pajato1 obtient le crédit pour la résolution du problème de synchronisation, tel que cité dans les commentaires de réponses acceptées.

 /** * Creates a test Activity for a given fully qualified test class name. * * @param fullyQualifiedClassName The fully qualified name of test activity class. * * @return The test activity object or null if it could not be located. */ protected AbstractTestActivity getTestActivity(final Ssortingng fullyQualifiedClassName) { AbstractTestActivity result = null; // Register our interest in the given activity and start it. Log.d(TAG, Ssortingng.format("Running test (%s) with main class: %s.", getName(), fullyQualifiedClassName)); instrumentation = getInstrumentation(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClassName(instrumentation.getTargetContext(), fullyQualifiedClassName); // Wait for the activity to finish starting Activity activity = instrumentation.startActivitySync(intent); // Perform basic sanity checks. assertTrue("The activity is null! Aborting.", activity != null); Ssortingng format = "The test activity is of the wrong type (%s)."; assertTrue(Ssortingng.format(format, activity.getClass().getName()), activity.getClass().getName().equals(fullyQualifiedClassName)); result = (AbstractTestActivity) activity; return result; } 

Essayez le test de l’outil Monkey

Étape 1:

ouvrir le terminal du studio Android (Outils-> terminal ouvert)

Étape 2:

Pour utiliser monkey, ouvrez une invite de commande et naviguez simplement dans le répertoire suivant.

  export PATH=$PATH:/home/adt-bundle-linux-x86-20140702/sdk/platform-tools 

Étape 3:

ajoutez cette commande de singe au terminal et appuyez sur Entrée.

voir la magie dans votre émulateur.

 adb shell monkey -p com.example.yourpackage -v 500 

500- c’est le nombre de fréquences ou le nombre d’événements à envoyer pour les tests.

vous pouvez changer ce compte ..

Plus de référence,

http://www.tutorialspoint.com/android/android_testing.htm

http://androidtesting.blogspot.in/2012/04/android-testing-with-monkey-tool.html