Automatisiertes Testen in Android

on

  • 565 views

Speaker: Arne Limburg ...

Speaker: Arne Limburg
JAX 2013
23.4.2013

Nach wie vor beschränken sich Tests von mobilen Anwendungen meistens auf manuelle Tests im Emulator oder auf dem Endgerät. Häufig werden dann bei der Weiterentwicklung nur die neuen Features getestet. In dieser Session wird gezeigt, wie man das ändern kann. Dazu werden die verschiedenen Arten von automatisierten Tests und deren Einbindung in den Entwicklungsprozess an Beispielen vorgestellt.

Statistics

Views

Total Views
565
Views on SlideShare
535
Embed Views
30

Actions

Likes
0
Downloads
10
Comments
0

1 Embed 30

http://www.openknowledge.de 30

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Automatisiertes Testen in Android Automatisiertes Testen in Android Presentation Transcript

  • Arne Limburg |Arne Limburg | openopen knowledgeknowledge GmbHGmbH@ArneLimburg@ArneLimburg@_openknowledge@_openknowledge
  • Meine PersonArne LimburgHead of Developmentopen knowledge GmbH@ArneLimburg@_openknowledgewww.openknowledge.de
  • Herausforderungen• Vielfalt der Geräte• Bildschirmauflösung• Eingabemethode• Capabilities• Vielfalt der Umwelteinflüsse• Umgebung (Netz, Batterie, Standort)• Nutzerverhalten
  • Was tun?Rechne mit allem!Rechne mit nichts!Testen, Testen, Testen!
  • Testen• Konzentration auf das Wesentliche– Geräte– Android-Versionen– Länder– Operatoren• Test-Automatisierung
  • Unit-TestsTesten - Agenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsUnit-Tests
  • Unit-Testing„A unit is the smallest testable part of an application.“http://en.wikipedia.org/wiki/Unit_testing
  • Ziel von Unit-Testing• korrekte Funktionsweisevon kleinen Einheiten der Software(Testen von einzelnem Verhalten)• Automatisch• Regelmäßig (Continuous Integration)• Regressionssicher
  • Android Testing Framework• JUnit-Unterstützungfür On-Device-Testing• Oberklassen zum Testenvon Android-Komponenten• Activity• Content-Provider• Service• …
  • Mock-Kontexte• MockContext• Alle Methoden werfen Exception• IsolatedContext• Isolation vom Device• Datenbank- und Datei-Operationen möglich• RenamingDelegatingContext• Kommunikation mit dem Device möglich• Datenbank- und Datei-Operationen werdenumgeleitet
  • Android Testing - Architektur
  • Unit-Test-Klassenhierarchiejunit.framework.TestCaseAndroidTestCase InstrumentationTestCasePackage android.testApplicationTestCaseLoaderTestCaseProviderTestCase2ServiceTestCaseActivityTestCaseActivityUnitTestCaseActivityInstrumentationTestCase2
  • PoviderTestCase2• Testen eines isolierten Content-Providers• Verwendung von IsolatedContext• Bereitstellen eines MockContentResolversAPIsetContext(Context) (von AndroidTestCase)getMockContentResolver()getProvider
  • ProviderTestCase2public class PositionProviderTest extendsProviderTestCase2<PositionProvider> {public PositionProviderTest() {super(PositionProvider.class,PositionProvider.AUTHORITY);}public void testInsert() {…}
  • ServiceTestCase• Standardmäßig mit „echtem“ Context undMockApplication• Herausforderung: Testen von ThreadingAPIsetApplication(Application)setContext(Context) (von AndroidTestCase)startService(Intent)bindService(Intent)
  • ServiceTestCasepublic class UpdaterServiceTest extendsServiceTestCase<UpdaterService> {public UpdaterServiceTest() {super(UpdaterService.class);}public void testStartService() {…}}
  • Code Diving ...
  • ActivityUnitTestCase• Leitet von InstrumentationTestCase ab• Isoliertes Testen einer ActivityAPI (Auszug)getStartedActivityIntent()getStartedActivityRequest()getRequestOrientation()isFinishedCalled()
  • ActivityUnitTestCasepublic class Positio…ActivityUnitTest extendsActivityUnitTestCase<Position…Activity> {public PositionOverviewActivityUnitTest() {super(PositionOverviewActivity.class);}public void testOnListItemClick() {…}}
  • Activity startenpublic void testOnListItemClick() {Instrumentation i = getInstrumentation();Context context = i.getTargetContext();Intent intent= new Intent(context, Pos…Activity.class);startActivity(intent, null, null);…}
  • Test durchführenpublic void testOnListItemClick() {…int p = 42;AdapterView view= new MockAdapterView();getActivity().onItemClick(view, null, p, 0);…}
  • Ergebnis prüfenpublic void testOnListItemClick() {…Intent startedIntent= getStartedActivityIntent();assertNotNull(startedIntent);assertEquals(…, startedIntent.getComponent().getClassName());assertEquals(…, startedIntent.getSerializableExtra(…));…}
  • Code Diving ...
  • Unit-Tests• Herausforderung:Umgang mit Abhängigkeiten• Klassisches Vorgehen:Erstellen von Mocks• On-Device: Mock-Implementierungen desAndroid Testing Frameworks• Off-Device: Gängige Java-Mocking-Frameworks (EasyMock, Mockito, ...)
  • Off-Device-Testing• Herausforderung:Android ≠ Javajava.lang.RuntimeException: Stub!Off-Device– Instantiieren– Mocking via Java-Mocking-Frameworks– Zugriff auf Android-Interna• Lösung: Robolectric
  • Robolectric• Instantiieren von Android-Klassen• Shadowing• Zugriff auf Resourcen• ...
  • Robolectric@RunWith(RobolectricTestRunner.class)public class PositionOverviewActivityTest {@Testpublic void onItemClick() {…}…}
  • Activity erzeugen@Testpublic void onItemClick() {PositionOverviewActivity activity= new PositionOverviewActivity();…}JUnit4!Erzeugung mit new
  • Test durchführen@Testpublic void onItemClick() {…AdapterView<?> view= Mockito.mock(AdapterView.class);activity.onItemClick(view, …);…}Verwendung von Java Mocking-Frameworks
  • Ergebnis prüfen@Testpublic void onItemClick() {…ShadowActivity shadow = shadowOf(activity);Intent startedIntent= shadow.getNextStartedActivity();…}
  • Code Diving ...
  • Continuous Integration• Regelmäßiges Bauen und Testen(CI-Server)z.B. Jenkins• Voraussetzung: Automatisiertes Bauenund TestenAnt oder Maven• Zusatzfeature:Code-Abdeckung mit EMMA
  • Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsUnit-TestsFunktionstests
  • Funktionstests• Testen der Interaktion mit der Umgebung• Testaufbau• UI-Verhalten• Klickpfade• State-Saving / -Restoring• Testinhalt• Änderung der Konfiguration (Orientierung,Sprache, Tastatur, Location)• Änderung der Ressourcen (Batterie, Netzwerk,Bluetooth, GPS• Eingehender Anruf / SMS• Tool: Auch Android JUnit
  • Unit-Test-Klassenhierarchiejunit.framework.TestCaseAndroidTestCase InstrumentationTestCasePackage android.testApplicationTestCaseLoaderTestCaseProviderTestCase2ServiceTestCaseActivityTestCaseActivityUnitTestCaseActivityInstrumentationTestCase2
  • InstrumentationTestCase• API (Auszug)<T> T launchActivity(String, Class<T>, Bundle)<T> T launchActivityWithIntent(String, Class<T>, Intent)void sendKeys(String)void sendKeys(int…)void sendRepeatedKeys(int…)Instrumentation getInstrumentation()
  • Instrumentation• API (Auszug)ActivityMonitor addMonitor(…)Activity waitForMonitor(…)Activity waitForMonitorWithTimeout(…)void startActivitySync(…)void sendXXXSync(…)void startPerformanceSnapshot()void endPerformanceSnapshot()void startProfiling()Void stopProfiling()
  • ActivityInstrumentationTestCase2• Leitet von InstrumentationTestCase ab• Testen von UI-Verhalten Testen eines gesamten Worksflows• Erzeugen von TouchEvents mitTouchUtils• Überprüfen von Layout mit ViewAsserts• Eventuell Verwendung von Third-Party-Framework (Robotium)
  • ActivityInstrumentationTestCase2public class Position…ActivityUiTest extendsActivityInstrumentationTestCase2<Pos…ity> {public PositionOverviewActivityUiTest() {super(PositionOverviewActivity.class);}public void testClickOnList() {…}}
  • Liste holenpublic void testClickOnList() {ListView list= (ListView)getActivity().findViewById(…);…}
  • Verhalten monitorenpublic void testClickOnList() {…Instrumentation i = getInstrumentation();ActivityMonitor monitor= i.addMonitor(Pos…DetailActivity.class, ……}
  • Test durchführenpublic void testClickOnList() {…TouchUtils.clickView(this,list.getChildAt(0));…}
  • Ergebnis prüfenpublic void testClickOnList() {…Pos…DetailActivity detail= monitor.waitForActivity();TextView view= (TextView)detail.findViewById(…);…}
  • Code Diving ...
  • ActivityUnitTestCase vs.ActivityInstrumentationTestCase2ActivityUnitTestCase•Reines Testen desCodes•Kein Test des UI-Verhaltens•Kein Test desWorkflow-VerhaltensActivityInstr…TestCase2•Testen des UI-Verhaltens•Testen des Workflow-Verhaltens
  • Robotium• Selenium nur für Android• Baut auf Instrumentation auf• Weniger komplex zu bedienen• Black-Box-Testing möglich
  • Robotium• Selenium nur für Android• Baut auf Instrumentation auf• Weniger komplex zu bedienen• Black-Box-Testing möglich
  • Code Diving ...
  • Android Emulator fernsteuern• Steuerung von Geo-Koordinaten,Telefonie, Netzwerk (Geschwindigkeit,Delay), Batterie, SMS, Sensoren• DDMS-Perspektive in Eclipse• Verbinden via TelnetBeispiel:telnet localhost 5554
  • Continuous IntegrationBest Practice•Funktionstests selten ausführen•Klassifizierung von Tests@SmallTest– „Echter“ Unit-Test (ActivityUnitTest)@MediumTest– Test einer Komponente mit Umgebung@LargeTest– Workflow-Test (gesamter Use-Case)
  • Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsFunktionstestsAbnahme- und Regressionstests
  • MonkeyRunnerCreative Commons by Simon Englisch
  • MonkeyRunner• Python / Jython• Testen kompletter Use-Cases• Vergleichen der Ergebnisse überBildschirm-Fotos• Paralleles Testen verschiedenerDevices und Auflösungen via Scripting
  • MonkeyRunnerMonkeyRunner APIvoid alert(…), integer choice(…), string input(…)void sleep(…)MonkeyDevice waitForConnection(…)MonkeyDevice API (Auszug)void installPackage(…)void startActivity(…)Void broadcastIntent(…)void drag(…), void press(…), void touch(…), void type(…)MonkeyImage takeSnapshot()MonkeyImage API (Auszug)MonkeyImage getSubImage(…), boolean sameAs(…),void writeToFile(…)
  • Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsAbnahme- und RegressionstestsStresstests
  • Würden Sie einen Affen mitIhrem Telefon spielen lassen?© Rex Features
  • Monkey• Schicken zufälliger Events• Anzahl und Geschwindigkeitkonfigurierbar• Reihenfolge reproduzierbar (durchAngabe von seed)• Wahrscheinlichkeit einzelner Event-Arten konfigurierbarSuchen von spezifischen Bugs
  • Unit-TestsAgenda1234FunktionstestsRegressionstestsStresstestsStresstests
  • Fazit - Testing• Unit-Tests• Off Device (Robolectric)• On Device (Android Testing Framework)• Regelmäßig (Continuous Integration) mitSimulator• Vor der Auslieferung mit echten Geräten• Funktionale Tests• UI-Interaktion• Gesamter Workflow (automatisiert)• Regressionstests (MonkeyRunner)• Stresstests (Monkey)
  • Vielen Dank für Ihre Zeit.Kontakt:open knowledge GmbHBismarckstr. 1326122 Oldenburgarne.limburg@openknowledge.de@ArneLimburg@_openknowledgeQ&A