Android Testing Tutorial: Unit Testing wie ein True Green Droid
Veröffentlicht: 2022-03-11Als erfahrene App-Entwickler bekommen wir, wenn die von uns entwickelten Anwendungen ausgereift sind, ein Bauchgefühl, dass es an der Zeit ist, mit dem Testen zu beginnen. Geschäftsregeln implizieren oft, dass das System über verschiedene Releases hinweg Stabilität bieten muss. Idealerweise möchten wir auch den Build-Prozess automatisieren und die Anwendung automatisch veröffentlichen. Dazu benötigen wir Adnroid-Testtools, um sicherzustellen, dass der Build wie erwartet funktioniert.
Tests können das zusätzliche Maß an Vertrauen in die Dinge, die wir bauen, schaffen. Es ist schwierig (wenn nicht unmöglich), ein perfektes, fehlerfreies Produkt zu bauen. Daher wird es unser Ziel sein, unsere Erfolgschancen auf dem Markt zu verbessern, indem wir eine Testsuite einrichten, die neu eingeführte Fehler in unserer Anwendung schnell erkennt.
Wenn es um Android und die verschiedenen mobilen Plattformen im Allgemeinen geht, kann das Testen von Apps eine Herausforderung sein. Das Implementieren von Unit-Tests und das Befolgen von Prinzipien der testgetriebenen Entwicklung oder ähnlichem kann sich oft zumindest unintuitiv anfühlen. Dennoch ist das Testen wichtig und sollte nicht als selbstverständlich angesehen oder ignoriert werden. David, Kent und Martin haben die Vorteile und Fallstricke des Testens in einer Reihe von Gesprächen untereinander diskutiert, die in einem Artikel mit dem Titel „Ist TDD tot?“ zusammengestellt wurden. Dort finden Sie auch die eigentlichen Videogespräche und erhalten mehr Einblick, ob das Testen zu Ihrem Entwicklungsprozess passt und inwieweit Sie es ab sofort integrieren können.
In diesem Android-Test-Tutorial werde ich Sie durch Einheiten- und Akzeptanz- und Regressionstests auf Android führen. Wir werden uns auf die Abstraktion der Testeinheit auf Android konzentrieren, gefolgt von Beispielen für Akzeptanztests, wobei der Schwerpunkt darauf liegt, den Prozess so schnell und einfach wie möglich zu gestalten, um die Entwickler-QA-Feedbackzyklen zu verkürzen.
Soll ich es lesen?
In diesem Tutorial werden die verschiedenen Möglichkeiten zum Testen von Android-Anwendungen untersucht. Entwickler oder Projektmanager, die die aktuellen Testmöglichkeiten der Android-Plattform besser verstehen möchten, können anhand dieses Tutorials entscheiden, ob sie einen der in diesem Artikel genannten Ansätze verfolgen möchten. Dies ist jedoch kein Allheilmittel, da die Diskussion um ein solches Thema naturgemäß von Produkt zu Produkt variiert, zusammen mit Fristen, Codebasisqualität des Codes, Kopplungsgrad des Systems, Präferenz des Entwicklers beim Architekturdesign, voraussichtliche Lebensdauer des Features zu testen usw.
In Einheiten denken: Android Testing
Idealerweise wollen wir eine logische Einheit/Komponente einer Architektur unabhängig testen. Auf diese Weise können wir garantieren, dass unsere Komponente für den von uns erwarteten Satz von Eingaben ordnungsgemäß funktioniert. Die Abhängigkeiten können verspottet werden, was es uns ermöglicht, Tests zu schreiben, die schnell ausgeführt werden. Darüber hinaus werden wir in der Lage sein, basierend auf dem gelieferten Input für den Test verschiedene Systemzustände zu simulieren und dabei exotische Fälle abzudecken.
Das Ziel von Android-Komponententests besteht darin, jeden Teil des Programms zu isolieren und zu zeigen, dass die einzelnen Teile korrekt sind. Ein Unit-Test stellt einen strengen, schriftlichen Vertrag dar, den das Codestück erfüllen muss. Als Ergebnis bietet es mehrere Vorteile. —Wikipedia
Roboterelektrik
Robolectric ist ein Framework für Android-Einheitentests, mit dem Sie Tests innerhalb der JVM auf Ihrer Entwicklungs-Workstation ausführen können. Robolectric schreibt Android-SDK-Klassen neu, während sie geladen werden, und macht es möglich, dass sie auf einer regulären JVM ausgeführt werden, was zu schnellen Testzeiten führt. Darüber hinaus verarbeitet es das Aufblähen von Ansichten, das Laden von Ressourcen und mehr Dinge, die in nativem C-Code auf Android-Geräten implementiert sind, wodurch die Notwendigkeit von Emulatoren und physischen Geräten zum Ausführen automatisierter Tests überflüssig wird.
Mockito
Mockito ist ein spöttisches Framework, das es uns ermöglicht, saubere Tests in Java zu schreiben. Es vereinfacht den Prozess der Erstellung von Testdoubles (Mocks), die verwendet werden, um die ursprünglichen Abhängigkeiten einer Komponente/eines Moduls zu ersetzen, die in der Produktion verwendet werden. Eine StackOverflow-Antwort diskutiert die Unterschiede zwischen Mocks und Stubs in ziemlich einfachen Begriffen, die Sie lesen können, um mehr zu erfahren.
// you can mock concrete classes, not only interfaces LinkedList mockedList = mock(LinkedList.class); // stubbing appears before the actual execution when(mockedList.get(0)).thenReturn("first"); // the following prints "first" System.out.println(mockedList.get(0)); // the following prints "null" because get(999) was not stubbed System.out.println(mockedList.get(999));
Außerdem können wir mit Mockito überprüfen, ob eine Methode aufgerufen wurde:
// mock creation List mockedList = mock(List.class); // using mock object - it does not throw any "unexpected interaction" exception mockedList.add("one"); mockedList.clear(); // selective, explicit, highly readable verification verify(mockedList).add("one"); verify(mockedList).clear();
Jetzt wissen wir, dass wir Aktions-Reaktions-Paare angeben können, die definieren, was passiert, wenn wir eine bestimmte Aktion auf dem verspotteten Objekt/der Komponente ausführen. Daher können wir ganze Module unserer Anwendung verspotten und das verspottete Modul für jeden Testfall anders reagieren lassen. Die unterschiedlichen Wege werden die möglichen Zustände der getesteten Komponente und des simulierten Komponentenpaars widerspiegeln.
Unit-Tests
In diesem Abschnitt gehen wir von einer MVP-Architektur (Model View Presenter) aus. Die Aktivitäten und Fragmente sind die Ansichten, Modelle sind die Repository-Schicht für Aufrufe an die Datenbank oder Remote-Dienste, und der Presenter ist das „Gehirn“, das all diese miteinander verbindet und eine spezifische Logik implementiert, um Ansichten, Modelle und den Datenfluss durch die zu steuern Anwendung.
Abstrahierende Komponenten
Spottansichten und Models
In diesem Android-Testbeispiel werden wir Ansichten, Modelle und Repository-Komponenten simulieren und den Presenter einem Komponententest unterziehen. Dies ist einer der kleinsten Tests, der auf eine einzelne Komponente in der Architektur abzielt. Darüber hinaus werden wir Method Stubbing verwenden, um eine ordnungsgemäße, überprüfbare Reaktionskette aufzubauen:
@RunWith(RobolectricTestRunner.class) @Config(manifest = "app/src/main/AndroidManifest.xml", emulateSdk = 18) public class FitnessListPresenterTest { private Calendar cal = Calendar.getInstance(); @Mock private IFitnessListModel model; @Mock private IFitnessListView view; private IFitnessListPresenter presenter; @Before public void setup() { MockitoAnnotations.initMocks(this); final FitnessEntry entryMock = mock(FitnessEntry.class); presenter = new FitnessListPresenter(view, model); /* Define the desired behaviour. Queuing the action in "doAnswer" for "when" is executed. Clear and synchronous way of setting reactions for actions (stubbing). */ doAnswer((new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { ArrayList<FitnessEntry> items = new ArrayList<>(); items.add(entryMock); ((IFitnessListPresenterCallback) presenter).onFetchAllSuccess(items); return null; } })).when(model).fetchAllItems((IFitnessListPresenterCallback) presenter); } /** Verify if model.fetchItems was called once. Verify if view.onFetchSuccess is called once with the specified list of type FitnessEntry The concrete implementation of ((IFitnessListPresenterCallback) presenter).onFetchAllSuccess(items); calls the view.onFetchSuccess(...) method. This is why we verify that view.onFetchSuccess is called once. */ @Test public void testFetchAll() { presenter.fetchAllItems(false); // verify can be called only on mock objects verify(model, times(1)).fetchAllItems((IFitnessListPresenterCallback) presenter); verify(view, times(1)).onFetchSuccess(new ArrayList<>(anyListOf(FitnessEntry.class))); } }
Verspotten der globalen Netzwerkschicht mit MockWebServer
Es ist oft bequem, die globale Netzwerkschicht nachahmen zu können. Mit MockWebServer können wir Antworten für bestimmte Anforderungen, die wir in unseren Tests ausführen, in eine Warteschlange stellen. Dies gibt uns die Möglichkeit, obskure Antworten zu simulieren, die wir vom Server erwarten, aber nicht einfach zu reproduzieren sind. Es ermöglicht uns, eine vollständige Abdeckung sicherzustellen, während wir wenig zusätzlichen Code schreiben.
Das Code-Repository von MockWebServer bietet ein nettes Beispiel, auf das Sie sich beziehen können, um diese Bibliothek besser zu verstehen.
Benutzerdefinierte Testdoppel
Sie können Ihr eigenes Modell oder Ihre eigene Repository-Komponente schreiben und in den Test einfügen, indem Sie mit Dagger (http://square.github.io/dagger/) ein anderes Modul für das Objektdiagramm bereitstellen. Wir haben die Möglichkeit zu überprüfen, ob der Ansichtsstatus ordnungsgemäß aktualisiert wurde, basierend auf den Daten, die von der verspotteten Modellkomponente geliefert werden:
/** Custom mock model class */ public class FitnessListErrorTestModel extends FitnessListModel { // ... @Override public void fetchAllItems(IFitnessListPresenterCallback callback) { callback.onError(); } @Override public void fetchItemsInRange(final IFitnessListPresenterCallback callback, DateFilter filter) { callback.onError(); } }
@RunWith(RobolectricTestRunner.class) @Config(manifest = "app/src/main/AndroidManifest.xml", emulateSdk = 18) public class FitnessListPresenterDaggerTest { private FitnessActivity activity; private FitnessListFragment fitnessListFragment; @Before public void setup() { /* setupActivity runs the Activity lifecycle methods on the specified class */ activity = Robolectric.setupActivity(FitnessActivity.class); fitnessListFragment = activity.getFitnessListFragment(); /* Create the objectGraph with the TestModule */ ObjectGraph localGraph = ObjectGraph.create(TestModule.newInstance(fitnessListFragment)); /* Injection */ localGraph.inject(fitnessListFragment); localGraph.inject(fitnessListFragment.getPresenter()); } @Test public void testInteractorError() { fitnessListFragment.getPresenter().fetchAllItems(false); /* suppose that our view shows a Toast message with the specified text below when an error is reported, so we check for it. */ assertEquals(ShadowToast.getTextOfLatestToast(), "Something went wrong!"); } @Module( injects = { FitnessListFragment.class, FitnessListPresenter.class }, overrides = true, library = true ) static class TestModule { private IFitnessListView view; private TestModule(IFitnessListView view){ this.view = view; } public static TestModule newInstance(IFitnessListView view){ return new TestModule(view); } @Provides public IFitnessListInteractor provideFitnessListInteractor(){ return new FitnessListErrorTestModel(); } @Provides public IFitnessListPresenter provideFitnessPresenter(){ return new FitnessListPresenter(view); } } }
Laufende Tests
Android-Studio
Sie können ganz einfach mit der rechten Maustaste auf eine Testklasse, Methode oder ein ganzes Testpaket klicken und die Tests über das Optionsdialogfeld in der IDE ausführen.
Terminal
Durch das Ausführen von Android-App-Tests über das Terminal werden Berichte für die getesteten Klassen im „Build“-Ordner des Zielmoduls erstellt. Mehr noch, wenn Sie vorhaben, einen automatisierten Build-Prozess einzurichten, werden Sie den Terminal-Ansatz verwenden. Mit Gradle können Sie alle Debug-Tests ausführen, indem Sie Folgendes ausführen:
gradle testDebug
Zugriff auf Source Set „test“ von der Android Studio-Version
Version 1.1 von Android Studio und das Android Gradle-Plug-in bieten Unterstützung für Komponententests Ihres Codes. Sie können mehr erfahren, indem Sie ihre ausgezeichnete Dokumentation dazu lesen. Die Funktion ist experimentell, aber auch eine großartige Integration, da Sie jetzt einfach zwischen Ihren Einheitentests und Instrumentierungstest-Quellsätzen aus der IDE wechseln können. Es verhält sich genauso, als ob Sie in der IDE die Flavors wechseln würden.
Erleichterung des Prozesses
Das Schreiben von Android-App-Tests macht möglicherweise nicht so viel Spaß wie das Entwickeln der ursprünglichen Anwendung. Daher werden einige Tipps, wie Sie den Prozess des Schreibens von Tests vereinfachen und häufige Probleme beim Einrichten des Projekts vermeiden können, sehr hilfreich sein.
AssertJ Android
AssertJ Android ist, wie Sie vielleicht anhand des Namens erraten haben, eine Reihe von Hilfsfunktionen, die für Android entwickelt wurden. Es ist eine Erweiterung der beliebten Bibliothek AssertJ. Die von AssertJ Android bereitgestellte Funktionalität reicht von einfachen Behauptungen wie „assertThat(view).isGone()“ bis hin zu so komplexen Dingen wie:

assertThat(layout).isVisible() .isVertical() .hasChildCount(4) .hasShowDividers(SHOW_DIVIDERS_MIDDLE)
Mit AssertJ Android und seiner Erweiterbarkeit ist Ihnen ein einfacher und guter Ausgangspunkt zum Schreiben von Tests für Android-Anwendungen garantiert.
Roboelektrischer und manifestierter Pfad
Während Sie Robolectric verwenden, stellen Sie möglicherweise fest, dass Sie den Speicherort des Manifests angeben müssen und dass die SDK-Version auf 18 festgelegt ist. Sie können dies tun, indem Sie eine „Config“-Anmerkung hinzufügen.
@Config(manifest = "app/src/main/AndroidManifest.xml", emulateSdk = 18)
Das Ausführen von Tests, die Robolectric vom Terminal erfordern, kann neue Herausforderungen mit sich bringen. Beispielsweise sehen Sie möglicherweise Ausnahmen wie „Design nicht festgelegt“. Wenn die Tests ordnungsgemäß von der IDE, aber nicht vom Terminal ausgeführt werden, versuchen Sie möglicherweise, sie von einem Pfad im Terminal auszuführen, in dem der angegebene Manifestpfad nicht aufgelöst werden kann. Der hartcodierte Konfigurationswert für den Manifestpfad zeigt möglicherweise nicht auf den richtigen Speicherort vom Ausführungspunkt des Befehls. Dies kann durch die Verwendung von benutzerdefinierten Läufern gelöst werden:
public class RobolectricGradleTestRunner extends RobolectricTestRunner { public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError { super(testClass); } @Override protected AndroidManifest getAppManifest(Config config) { String appRoot = "../app/src/main/"; String manifestPath = appRoot + "AndroidManifest.xml"; String resDir = appRoot + "res"; String assetsDir = appRoot + "assets"; AndroidManifest manifest = createAppManifest(Fs.fileFromPath(manifestPath), Fs.fileFromPath(resDir), Fs.fileFromPath(assetsDir)); return manifest; } }
Gradle-Konfiguration
Sie können Folgendes verwenden, um Gradle für Komponententests zu konfigurieren. Möglicherweise müssen Sie die erforderlichen Abhängigkeitsnamen und -versionen basierend auf Ihren Projektanforderungen ändern.
// Robolectric testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.9.5' testCompile 'com.squareup.dagger:dagger:1.2.2' testProvided 'com.squareup.dagger:dagger-compiler:1.2.2' testCompile 'com.android.support:support-v4:21.0.+' testCompile 'com.android.support:appcompat-v7:21.0.3' testCompile('org.robolectric:robolectric:2.4') { exclude module: 'classworlds' exclude module: 'commons-logging' exclude module: 'httpclient' exclude module: 'maven-artifact' exclude module: 'maven-artifact-manager' exclude module: 'maven-error-diagnostics' exclude module: 'maven-model' exclude module: 'maven-project' exclude module: 'maven-settings' exclude module: 'plexus-container-default' exclude module: 'plexus-interpolation' exclude module: 'plexus-utils' exclude module: 'wagon-file' exclude module: 'wagon-http-lightweight' exclude module: 'wagon-provider-api' }
Robolectric- und Spieldienste
Wenn Sie Google Play Services verwenden, müssen Sie Ihre eigene ganzzahlige Konstante für die Play Services-Version erstellen, damit Robolectric in dieser Anwendungskonfiguration ordnungsgemäß funktioniert.
<meta-data android:name="com.google.android.gms.version" android:value="@integer/gms_version" tools:replace="android:value" />
Robolectric-Abhängigkeiten zur Unterstützung von Bibliotheken
Ein weiteres interessantes Testproblem besteht darin, dass Robolectric nicht in der Lage ist, Support-Bibliotheken richtig zu referenzieren. Die Lösung besteht darin, dem Modul, in dem sich die Tests befinden, eine Datei „project.properties“ hinzuzufügen. Beispielsweise sollte die Datei für die Support-v4- und AppCompat-Bibliotheken Folgendes enthalten:
android.library.reference.1=../../build/intermediates/exploded-aar/com.android.support/support-v4/21.0.3 android.library.reference.2=../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/21.0.3
Akzeptanz-/Regressionstests
Akzeptanz-/Regressionstests automatisieren einen Teil des letzten Testschritts in einer echten, 100-prozentigen Android-Umgebung. Wir verwenden auf dieser Ebene keine verspotteten Android-Betriebssystemklassen – die Tests werden auf echten Geräten und Emulatoren ausgeführt.
Diese Umstände machen den Prozess aufgrund der Vielzahl von physischen Geräten, Emulatorkonfigurationen, Gerätezuständen und Funktionssätzen jedes Geräts viel instabiler. Darüber hinaus hängt es stark von der Version des Betriebssystems und der Bildschirmgröße des Telefons ab, wie die Inhalte angezeigt werden.
Es ist ein bisschen komplex, den richtigen Test zu erstellen, der eine Vielzahl von Geräten übergibt, aber wie immer sollten Sie groß träumen, aber klein anfangen. Die Erstellung von Tests mit Robotium ist ein iterativer Prozess. Mit ein paar Tricks lässt sich vieles vereinfachen.
Robotium
Robotium ist ein Open-Source-Android-Testautomatisierungs-Framework, das seit Januar 2010 existiert. Es ist erwähnenswert, dass Robotium eine kostenpflichtige Lösung ist, aber mit einer fairen kostenlosen Testversion geliefert wird.
Um den Prozess des Schreibens von Robotium-Tests zu beschleunigen, werden wir von der manuellen Testerstellung zur Testaufzeichnung übergehen. Der Kompromiss besteht zwischen Codequalität und Geschwindigkeit. Wenn Sie umfangreiche Änderungen an Ihrer Benutzeroberfläche vornehmen, profitieren Sie sehr vom Testaufzeichnungsansatz und der Möglichkeit, neue Tests schnell aufzuzeichnen.
Testdroid Recorder ist ein kostenloser Testrecorder, der Robotium-Tests erstellt, während er die Klicks aufzeichnet, die Sie auf der Benutzeroberfläche ausführen. Die Installation des Tools ist super einfach, wie in der Dokumentation beschrieben, begleitet von einem Schritt-für-Schritt-Video.
Da Testdroid Recorder ein Eclipse-Plugin ist und wir uns in diesem Artikel auf Android Studio beziehen, wäre dies idealerweise ein Grund zur Besorgnis. In diesem Fall ist dies jedoch kein Problem, da Sie das Plugin direkt mit einer APK verwenden und die Tests dagegen aufzeichnen können.
Sobald Sie die Tests erstellt haben, können Sie sie kopieren und in Android Studio einfügen, zusammen mit allen Abhängigkeiten, die der Testdroid-Rekorder benötigt, und Sie können loslegen. Der aufgezeichnete Test würde etwa wie die folgende Klasse aussehen:
public class LoginTest extends ActivityInstrumentationTestCase2<Activity> { private static final String LAUNCHER_ACTIVITY_CLASSNAME = "com.toptal.fitnesstracker.view.activity.SplashActivity"; private static Class<?> launchActivityClass; static { try { launchActivityClass = Class.forName(LAUNCHER_ACTIVITY_CLASSNAME); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private ExtSolo solo; @SuppressWarnings("unchecked") public LoginTest() { super((Class<Activity>) launchActivityClass); } // executed before every test method @Override public void setUp() throws Exception { super.setUp(); solo = new ExtSolo(getInstrumentation(), getActivity(), this.getClass() .getCanonicalName(), getName()); } // executed after every test method @Override public void tearDown() throws Exception { solo.finishOpenedActivities(); solo.tearDown(); super.tearDown(); } public void testRecorded() throws Exception { try { assertTrue( "Wait for edit text (id: com.toptal.fitnesstracker.R.id.login_username_input) failed.", solo.waitForEditTextById( "com.toptal.fitnesstracker.R.id.login_username_input", 20000)); solo.enterText( (EditText) solo .findViewById("com.toptal.fitnesstracker.R.id.login_username_input"), "[email protected]"); solo.sendKey(ExtSolo.ENTER); solo.sleep(500); assertTrue( "Wait for edit text (id: com.toptal.fitnesstracker.R.id.login_password_input) failed.", solo.waitForEditTextById( "com.toptal.fitnesstracker.R.id.login_password_input", 20000)); solo.enterText( (EditText) solo .findViewById("com.toptal.fitnesstracker.R.id.login_password_input"), "123456"); solo.sendKey(ExtSolo.ENTER); solo.sleep(500); assertTrue( "Wait for button (id: com.toptal.fitnesstracker.R.id.parse_login_button) failed.", solo.waitForButtonById( "com.toptal.fitnesstracker.R.id.parse_login_button", 20000)); solo.clickOnButton((Button) solo .findViewById("com.toptal.fitnesstracker.R.id.parse_login_button")); assertTrue("Wait for text fitness list activity.", solo.waitForActivity(FitnessActivity.class)); assertTrue("Wait for text KM.", solo.waitForText("KM", 20000)); /* Custom class that enables proper clicking of ActionBar action items */ TestUtils.customClickOnView(solo, R.id.action_logout); solo.waitForDialogToOpen(); solo.waitForText("OK"); solo.clickOnText("OK"); assertTrue("waiting for ParseLoginActivity after logout", solo.waitForActivity(ParseLoginActivity.class)); assertTrue( "Wait for button (id: com.toptal.fitnesstracker.R.id.parse_login_button) failed.", solo.waitForButtonById( "com.toptal.fitnesstracker.R.id.parse_login_button", 20000)); } catch (AssertionFailedError e) { solo.fail( "com.example.android.apis.test.Test.testRecorded_scr_fail", e); throw e; } catch (Exception e) { solo.fail( "com.example.android.apis.test.Test.testRecorded_scr_fail", e); throw e; } } }
Wenn Sie genau hinsehen, werden Sie feststellen, wie viel des Codes ziemlich geradlinig ist.
Gehen Sie beim Aufzeichnen von Tests nicht auf „Warten“-Anweisungen ein. Warten Sie, bis Dialoge erscheinen, Aktivitäten erscheinen, Texte erscheinen. Dadurch wird sichergestellt, dass die Aktivität und die Ansichtshierarchie zur Interaktion bereit sind, wenn Sie die Aktion auf dem aktuellen Bildschirm ausführen. Machen Sie gleichzeitig Screenshots. Automatisierte Tests sind normalerweise unbeaufsichtigt, und Screenshots sind eine der Möglichkeiten, wie Sie sehen können, was während dieser Tests tatsächlich passiert ist.
Unabhängig davon, ob Tests bestanden werden oder nicht, Berichte sind Ihr bester Freund. Sie finden sie unter dem Build-Verzeichnis „module/build/outputs/reports“:
Theoretisch könnte das QA-Team Tests aufzeichnen und optimieren. Indem man sich um ein standardisiertes Modell zur Optimierung von Testfällen bemühte, konnte dies erreicht werden. Wenn Sie normalerweise Tests aufzeichnen, müssen Sie immer ein paar Dinge optimieren, damit es einwandfrei funktioniert.
Um diese Tests schließlich von Android Studio aus auszuführen, können Sie sie auswählen und ausführen, als würden Sie Komponententests ausführen. Vom Terminal aus ist es ein Einzeiler:
gradle connectedAndroidTest
Durchführung von Tests
Das Testen von Android-Einheiten mit Robolectric ist extrem schnell, da es direkt in der JVM auf Ihrem Computer ausgeführt wird. Im Vergleich dazu sind Akzeptanztests auf Emulatoren und physischen Geräten viel langsamer. Abhängig von der Größe der Flows, die Sie testen, kann es zwischen einigen Sekunden und einigen Minuten pro Testfall dauern. Die Akzeptanztestphase sollte als Teil eines automatisierten Build-Prozesses auf einem Continuous-Integration-Server verwendet werden.
Die Geschwindigkeit kann durch Parallelisierung auf mehreren Geräten verbessert werden. Sehen Sie sich dieses großartige Tool von Jake Wharton und den Jungs von Square http://square.github.io/spoon/ an. Es hat auch eine nette Berichterstattung.
Das wegnehmen
Es gibt eine Vielzahl von Android-Testtools, und mit zunehmender Reife des Ökosystems wird der Prozess der Einrichtung einer testfähigen Umgebung und des Schreibens von Tests einfacher. Es gibt noch weitere Herausforderungen zu bewältigen, und mit einer großen Community von Entwicklern, die an täglichen Problemen arbeiten, gibt es viel Raum für konstruktive Diskussionen und schnelles Feedback.
Verwenden Sie die in diesem Android-Testtutorial beschriebenen Ansätze, um Sie bei der Bewältigung der vor Ihnen liegenden Herausforderungen zu unterstützen. Wenn Sie auf Probleme stoßen, sehen Sie in diesem Artikel oder den darin verlinkten Referenzen nach, um Lösungen für bekannte Probleme zu finden.
In einem zukünftigen Beitrag werden wir Parallelisierung, Build-Automatisierung, kontinuierliche Integration, Github/BitBucket-Hooks, Artifact-Versionierung und die Best Practices für die Verwaltung umfangreicher mobiler Anwendungsprojekte ausführlicher diskutieren.