Automatisiertes Testen in Android

568 views
497 views

Published on

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.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
568
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Automatisiertes Testen in Android

  1. 1. Arne Limburg |Arne Limburg | openopen knowledgeknowledge GmbHGmbH@ArneLimburg@ArneLimburg@_openknowledge@_openknowledge
  2. 2. Meine PersonArne LimburgHead of Developmentopen knowledge GmbH@ArneLimburg@_openknowledgewww.openknowledge.de
  3. 3. Herausforderungen• Vielfalt der Geräte• Bildschirmauflösung• Eingabemethode• Capabilities• Vielfalt der Umwelteinflüsse• Umgebung (Netz, Batterie, Standort)• Nutzerverhalten
  4. 4. Was tun?Rechne mit allem!Rechne mit nichts!Testen, Testen, Testen!
  5. 5. Testen• Konzentration auf das Wesentliche– Geräte– Android-Versionen– Länder– Operatoren• Test-Automatisierung
  6. 6. Unit-TestsTesten - Agenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsUnit-Tests
  7. 7. Unit-Testing„A unit is the smallest testable part of an application.“http://en.wikipedia.org/wiki/Unit_testing
  8. 8. Ziel von Unit-Testing• korrekte Funktionsweisevon kleinen Einheiten der Software(Testen von einzelnem Verhalten)• Automatisch• Regelmäßig (Continuous Integration)• Regressionssicher
  9. 9. Android Testing Framework• JUnit-Unterstützungfür On-Device-Testing• Oberklassen zum Testenvon Android-Komponenten• Activity• Content-Provider• Service• …
  10. 10. 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
  11. 11. Android Testing - Architektur
  12. 12. Unit-Test-Klassenhierarchiejunit.framework.TestCaseAndroidTestCase InstrumentationTestCasePackage android.testApplicationTestCaseLoaderTestCaseProviderTestCase2ServiceTestCaseActivityTestCaseActivityUnitTestCaseActivityInstrumentationTestCase2
  13. 13. PoviderTestCase2• Testen eines isolierten Content-Providers• Verwendung von IsolatedContext• Bereitstellen eines MockContentResolversAPIsetContext(Context) (von AndroidTestCase)getMockContentResolver()getProvider
  14. 14. ProviderTestCase2public class PositionProviderTest extendsProviderTestCase2<PositionProvider> {public PositionProviderTest() {super(PositionProvider.class,PositionProvider.AUTHORITY);}public void testInsert() {…}
  15. 15. ServiceTestCase• Standardmäßig mit „echtem“ Context undMockApplication• Herausforderung: Testen von ThreadingAPIsetApplication(Application)setContext(Context) (von AndroidTestCase)startService(Intent)bindService(Intent)
  16. 16. ServiceTestCasepublic class UpdaterServiceTest extendsServiceTestCase<UpdaterService> {public UpdaterServiceTest() {super(UpdaterService.class);}public void testStartService() {…}}
  17. 17. Code Diving ...
  18. 18. ActivityUnitTestCase• Leitet von InstrumentationTestCase ab• Isoliertes Testen einer ActivityAPI (Auszug)getStartedActivityIntent()getStartedActivityRequest()getRequestOrientation()isFinishedCalled()
  19. 19. ActivityUnitTestCasepublic class Positio…ActivityUnitTest extendsActivityUnitTestCase<Position…Activity> {public PositionOverviewActivityUnitTest() {super(PositionOverviewActivity.class);}public void testOnListItemClick() {…}}
  20. 20. Activity startenpublic void testOnListItemClick() {Instrumentation i = getInstrumentation();Context context = i.getTargetContext();Intent intent= new Intent(context, Pos…Activity.class);startActivity(intent, null, null);…}
  21. 21. Test durchführenpublic void testOnListItemClick() {…int p = 42;AdapterView view= new MockAdapterView();getActivity().onItemClick(view, null, p, 0);…}
  22. 22. Ergebnis prüfenpublic void testOnListItemClick() {…Intent startedIntent= getStartedActivityIntent();assertNotNull(startedIntent);assertEquals(…, startedIntent.getComponent().getClassName());assertEquals(…, startedIntent.getSerializableExtra(…));…}
  23. 23. Code Diving ...
  24. 24. 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, ...)
  25. 25. Off-Device-Testing• Herausforderung:Android ≠ Javajava.lang.RuntimeException: Stub!Off-Device– Instantiieren– Mocking via Java-Mocking-Frameworks– Zugriff auf Android-Interna• Lösung: Robolectric
  26. 26. Robolectric• Instantiieren von Android-Klassen• Shadowing• Zugriff auf Resourcen• ...
  27. 27. Robolectric@RunWith(RobolectricTestRunner.class)public class PositionOverviewActivityTest {@Testpublic void onItemClick() {…}…}
  28. 28. Activity erzeugen@Testpublic void onItemClick() {PositionOverviewActivity activity= new PositionOverviewActivity();…}JUnit4!Erzeugung mit new
  29. 29. Test durchführen@Testpublic void onItemClick() {…AdapterView<?> view= Mockito.mock(AdapterView.class);activity.onItemClick(view, …);…}Verwendung von Java Mocking-Frameworks
  30. 30. Ergebnis prüfen@Testpublic void onItemClick() {…ShadowActivity shadow = shadowOf(activity);Intent startedIntent= shadow.getNextStartedActivity();…}
  31. 31. Code Diving ...
  32. 32. Continuous Integration• Regelmäßiges Bauen und Testen(CI-Server)z.B. Jenkins• Voraussetzung: Automatisiertes Bauenund TestenAnt oder Maven• Zusatzfeature:Code-Abdeckung mit EMMA
  33. 33. Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsUnit-TestsFunktionstests
  34. 34. 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
  35. 35. Unit-Test-Klassenhierarchiejunit.framework.TestCaseAndroidTestCase InstrumentationTestCasePackage android.testApplicationTestCaseLoaderTestCaseProviderTestCase2ServiceTestCaseActivityTestCaseActivityUnitTestCaseActivityInstrumentationTestCase2
  36. 36. 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()
  37. 37. Instrumentation• API (Auszug)ActivityMonitor addMonitor(…)Activity waitForMonitor(…)Activity waitForMonitorWithTimeout(…)void startActivitySync(…)void sendXXXSync(…)void startPerformanceSnapshot()void endPerformanceSnapshot()void startProfiling()Void stopProfiling()
  38. 38. 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)
  39. 39. ActivityInstrumentationTestCase2public class Position…ActivityUiTest extendsActivityInstrumentationTestCase2<Pos…ity> {public PositionOverviewActivityUiTest() {super(PositionOverviewActivity.class);}public void testClickOnList() {…}}
  40. 40. Liste holenpublic void testClickOnList() {ListView list= (ListView)getActivity().findViewById(…);…}
  41. 41. Verhalten monitorenpublic void testClickOnList() {…Instrumentation i = getInstrumentation();ActivityMonitor monitor= i.addMonitor(Pos…DetailActivity.class, ……}
  42. 42. Test durchführenpublic void testClickOnList() {…TouchUtils.clickView(this,list.getChildAt(0));…}
  43. 43. Ergebnis prüfenpublic void testClickOnList() {…Pos…DetailActivity detail= monitor.waitForActivity();TextView view= (TextView)detail.findViewById(…);…}
  44. 44. Code Diving ...
  45. 45. ActivityUnitTestCase vs.ActivityInstrumentationTestCase2ActivityUnitTestCase•Reines Testen desCodes•Kein Test des UI-Verhaltens•Kein Test desWorkflow-VerhaltensActivityInstr…TestCase2•Testen des UI-Verhaltens•Testen des Workflow-Verhaltens
  46. 46. Robotium• Selenium nur für Android• Baut auf Instrumentation auf• Weniger komplex zu bedienen• Black-Box-Testing möglich
  47. 47. Robotium• Selenium nur für Android• Baut auf Instrumentation auf• Weniger komplex zu bedienen• Black-Box-Testing möglich
  48. 48. Code Diving ...
  49. 49. Android Emulator fernsteuern• Steuerung von Geo-Koordinaten,Telefonie, Netzwerk (Geschwindigkeit,Delay), Batterie, SMS, Sensoren• DDMS-Perspektive in Eclipse• Verbinden via TelnetBeispiel:telnet localhost 5554
  50. 50. 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)
  51. 51. Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsFunktionstestsAbnahme- und Regressionstests
  52. 52. MonkeyRunnerCreative Commons by Simon Englisch
  53. 53. MonkeyRunner• Python / Jython• Testen kompletter Use-Cases• Vergleichen der Ergebnisse überBildschirm-Fotos• Paralleles Testen verschiedenerDevices und Auflösungen via Scripting
  54. 54. 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(…)
  55. 55. Unit-TestsAgenda1234FunktionstestsAbnahme- und RegressionstestsStresstestsAbnahme- und RegressionstestsStresstests
  56. 56. Würden Sie einen Affen mitIhrem Telefon spielen lassen?© Rex Features
  57. 57. Monkey• Schicken zufälliger Events• Anzahl und Geschwindigkeitkonfigurierbar• Reihenfolge reproduzierbar (durchAngabe von seed)• Wahrscheinlichkeit einzelner Event-Arten konfigurierbarSuchen von spezifischen Bugs
  58. 58. Unit-TestsAgenda1234FunktionstestsRegressionstestsStresstestsStresstests
  59. 59. 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)
  60. 60. Vielen Dank für Ihre Zeit.Kontakt:open knowledge GmbHBismarckstr. 1326122 Oldenburgarne.limburg@openknowledge.de@ArneLimburg@_openknowledgeQ&A

×