Go for Quality - automatisiertes Testen in iOS
Upcoming SlideShare
Loading in...5
×
 

Go for Quality - automatisiertes Testen in iOS

on

  • 150 views

Für die Entwicklung konsequent stabiler Software, sind automatisierte Tests unabdingbar. Es geht nicht nur um das Auffinden von Fehlern, sondern darum, Komponenten einer Software funktional korrekt ...

Für die Entwicklung konsequent stabiler Software, sind automatisierte Tests unabdingbar. Es geht nicht nur um das Auffinden von Fehlern, sondern darum, Komponenten einer Software funktional korrekt und technisch stabil zu entwickeln. Dies gilt gerade für mobile Apps. Diese Session bietet eine Einführung in die Welt der automatisierten Tests unter iOS. Der Fokus liegt hierbei auf den Möglichkeiten von User Interface Tests. Damit hat der leidige Klick-Test nach jeder Änderung ein Ende und die App funktioniert auch nach dem nächsten Release wie gewohnt - versprochen!

Statistics

Views

Total Views
150
Slideshare-icon Views on SlideShare
146
Embed Views
4

Actions

Likes
1
Downloads
1
Comments
0

2 Embeds 4

http://www.slideee.com 3
http://translate.googleusercontent.com 1

Accessibility

Upload Details

Uploaded via as Adobe PDF

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
  • Last but not least Session für heute
  • Das können wir leider nicht
  • Wer ist der selben Meinung? <br /> Wenn das alle so sehen können wir aufhören und Feierabend machen! <br />
  • manuelles Testen besser, aber zeitintensiver! <br /> Beim Refactoring helfen Unit Tests Bugs zu finden
  • Robuster Code <br /> Mehr Bugfixing als neue Funktionen <br /> Sonst kein sicheres Refactoring möglich <br /> Unit Tests sind gute Dokumentation. Neue Teammitglieder können somit schneller und einfacher eingearbeitet werden
  • Manuelles Testen zu zeitintensiv
  • Da funktionieren die Tests sowieso immer
  • Der Kunde macht höchstens Abnahmetests
  • Kein Netz <br /> Device Orientation Change <br /> Verschiedene Auflösungen und Display Grössen
  • Keine Frameworks testen.
  • Vermeide doppelte Assertions <br /> Testen von kleinen Einheiten (deshalb Unit Test) <br /> Funktionieren auch bei fehlender Netzwerkverbindung <br /> Auch unabhängig von anderen Tests, Reihenfolge egal <br /> Das Ergebnis sollte immer das gleiche sein, ansonsten lässt sich kein Test schreiben <br />
  • Was ist ein Unit Test?
  • Unit Test Frameworks für Objective-C
  • OCUnit ist die Grundlage <br /> Wir wollen uns heute nur mit XCTest befassen
  • Kleines Testprogramm
  • Jeder Test muss von XCTestCase ableiten <br /> vor dem Ausführen der Testklasse <br /> nach dem kompletten Test <br /> vor jeder Test Methode <br /> nach jeder Test Methode <br /> jede Test Methode muss mit „test“ beginnen <br /> Reihenfolge ist nicht festgelegt, daher unabhängig designen <br />
  • Bei jeder Test Methode ein neuer Calculator
  • XCTAssertEqual vergleicht Ergebnis mit erwaretetem Wert -> schlägt sonst fehl
  • Das ist nicht die einzige Assertion.
  • Jetzt wollen wir uns mal ein bisschen Code ansehen
  • Auch hier gibt es einiges zu beachten <br /> Der Sinn des Lebens wird in einem anderen Thread berechnet, um den Haupt-Thread nicht auszulasten <br />
  • Welches Ergebnis hat dieser Test wohl? <br /> Hint: Per Anhalter durch die Galaxis: 42
  • NUR die Unit
  • Dazu gibt es OCMock <br /> Open Source <br /> Verhalten ist immer gleich
  • Beispiel: <br /> Verbindung zu Twitter <br /> View um Tweets anzuzeigen <br /> laden der Tweets <br /> Tweets zur View hinzufügen
  • Mock für TwitterConnection erzeugen <br /> Im Controller setzen <br /> bei Aufruf von displayTweets soll Array mit testTweet zurückgegeben werden
  • Mock für TweetView erzeugen und an Controller hängen <br /> erwartet, dass addTweet mit vorher erzeugtem testTweet aufgerufen wird <br /> eigentliche Methode aufrufen <br /> Expectation verifizieren <br /> Wir sehen ein Beispiel später
  • Unit Testing können wir jetzt.
  • Jetzt kommen wir zu UI Automation
  • Instruments: Apples Profiler für iOS Apps <br /> Ohne Accessibility ist das Element unsichtbar
  • Zusätzlich: <br /> Gestures (pinch to zoom) <br /> spezialisierte Methoden für Zugriff auf Elemente (textFields)
  • Ich gehe nicht jede Klasse durch, Zeit reicht nicht - Komplette Doku von Apple verfügbar
  • Die App ist hierarchisch aufgebaut <br /> localTarget (UIATarget): <br /> Device Information (Model, Version) <br /> Device Orientation (auch Änderung) <br /> Device Controls (Volume, lock, unlock) <br /> Gestures (pinch to zoom) <br /> Screenshot erzeugen <br /> Warten auf Elemente -> Delay (wichtig!) <br /> frontMostApp (UIAApplication) <br /> Zugriff auf MainWindow <br /> <br /> <br />
  • mainWindow (UIAWindow): <br /> Top Level Element wie tabBar, navigationBar <br />
  • Kann jedes Element im Baum sein. <br />
  • Elemente können über ihr Accessibility Label angesprochen werden <br />
  • Elemente antippen <br /> Textfelder befüllen <br /> Scrolling (Predicates)
  • Test wartet Timeout bis die nächste Aktion erfolgreich sein muss. <br /> <br /> Timeout Stack, Default ist 5 Sekunden <br /> Test pausieren mit Delay <br /> Wenn mal was nicht funktioniert, erst mal eine Sekunde warten ;-) <br />
  • Test starten mit logStart <br /> Wenn Test erfolgreich, logPass <br /> sonst logFail
  • Debugger ist nicht verfügbar <br /> logging auf Konsole, auch logError, logWarning <br /> Elementbaum loggen <br /> Kann von jedem Element aus aufgerufen werden <br /> Screenshots <br />
  • Sammlung von JavaScript Hilfsmethoden um Testen zu vereinfachen <br /> Test Name und Closure mit Target und Application <br /> XCTest-ähnliche Assertions
  • Ganze Element Bäume prüfen
  • Open Source Integration Test Framework <br />
  • Integriert in Xcode <br /> Tests können wir normale Tests gestartet werden. <br /> benötigt ebenfalls Accessibilty
  • Schnittstelle zu UI Elementen <br /> Common tasks
  • Darf nicht zum Main Target hinzugefügt werden, da KIF private API von Apple nutzt
  • Sprache: Muss jeder für sich selbst entscheiden, was ihm besser gefällt <br /> Ausgelagert in Instruments oder integriert in XCode <br /> Debugging ist großes Manko von UI Automation <br /> Mocking kann ganz praktisch sein <br /> CI mit UI Automation komplizierter aber möglich <br />
  • Eine kleine Anekdote zum Abschluss: <br /> Die Broken Windows Theorie beschreibt ein Experiment des Psychologen Zimbardo aus den USA von 1969. <br /> Er stellte ein Auto in einer sozial intakten Gegend in Palo Alto ab. Über eine Woche lang stand das Auto dort unverändert. Als Zimbardo ein Fenster einschlug, fingen die Passanten ebenfalls an, das Auto zu demolieren. <br /> <br /> Was hat das jetzt mit Testing zu tun? <br /> Es ist wichtig, dass Unit Tests stabil sind und gepflegt werden.
  • In diesem Sinne!

Go for Quality - automatisiertes Testen in iOS Go for Quality - automatisiertes Testen in iOS Presentation Transcript

  • Go for Quality - automatisiertes Testen in iOS Michael Kotten | open knowledge GmbH @michaelkotten @_openKnowledge
  • MTD 2014 „Chuck Norris can unit test entire applications with a single assert.“ Facts of the day Go for Quality - automatisiertes Testen in iOS
  • Warum testen? Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • „Wer testet, ist feige!“ „Ich weiß doch, dass mein Code funktioniert!“ „Wenn ich den Test selber schreibe, hat es eh keinen Sinn!“ „Keine Zeit für Unit Tests!“ Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation „Unit testing is not about finding bugs.“
  • ‣  Notwendig bei komplexen Systemen ‣  Sicherung von ‣  Qualität ‣  Funktionalität ‣  Wichtig bei agilen Entwicklungsprozessen ‣  Schnelle Entwicklungszyklen Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • Wie testen? Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • eXtreme Clicking Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • nur auf dem Entwicklerrechner Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Kunden Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014 Expect the Unexpected!
  • Anforderungen an Testabdeckung ‣  Alles “Offensichtliche” plus …" ‣  … Umwelteinflüsse & Störungen ‣  … System Notifications ‣  … zu unterstützende Devices, Locales … Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Was testen? Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Motivation „It makes no sense " to test something that " can’t be broken (or fixed)!“ (Zitat: alter weiser Mann)
  • Gute Tests ... ‣ … treffen Annahmen nur einmal ‣ … sind isoliert ‣ … laufen unabhängig ‣ … sind vorhersehbar Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Unit Test ‣  Testen der korrekten Funktionsweise einzelner, isolierter Komponenten ‣  Automatisiert ‣  Wiederholbar Motivation Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Tests in Action Go for Quality - automatisiertes Testen in iOS MTD 2014
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action OCUnit a.k.a SenTestingKit ‣  basiert auf SUnit* von Kent Beck ‣  eingeführt 2005 mit Xcode 2.1 ‣  seit Xcode 5 obsolet * Mutter aller Test Frameworks
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action XCTest ‣  Apple-eigenes Test Framework ‣  ähnelt stark OCUnit ‣  Standard Test Framework seit Xcode 5
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @interface Calculator : NSObject -(int) add:(int)a to:(int)b; -(int) subtract:(int)a from:(int)b; -(float) divide:(int)a by:(int)b; @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @interface CalculatorTests : XCTestCase @end @implementation CalculatorTests + (void) setUp {...} + (void) tearDown {...} - (void) setUp {...} - (void) tearDown {...} - (void) testMyMethod {...} @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action #import "Calculator.h" @interface CalculatorTests : XCTestCase { Calculator* calculator; } @end @implementation CalculatorTests - (void) setUp { calculator = [[Calculator alloc] init]; } @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @implementation CalculatorTests - (void) setUp { calculator = [[Calculator alloc] init]; } - (void) testAdd { int result = [calculator add:5 to:6]; XCTAssertEqual(result, 11, @"result should be 11"); } @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action XCTFail (format…) XCTAssertNil (a1, format…) XCTAssertNotNil (a1, format…) XCTAssert (a1, format…) XCTAssertTrue (a1, format…) XCTAssertFalse (a1, format…) XCTAssertEqualObjects (a1, a2, format…) XCTAssertEquals (a1, a2, format…) XCTAssertEqualsWithAccuracy (a1, a2, accuracy, format…) XCTAssertThrows (expression, format…) XCTAssertThrowsSpecific (expression, specificException, format…) XCTAssertThrowsSpecificNamed (expression, specificException, exceptionName, format…) XCTAssertNoThrow (expression, format…) XCTAssertNoThrowSpecific (expression, specificException, format…) XCTAssertNoThrowSpecificNamed (expression, specificExcepton, exceptionName, format…) * siehe XCTestAssertions.h
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Code Diving CalculatorTests
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Pitfall 1: Multithreading @interface Calculator : NSObject ... -(void) calculateSenseOfLife:(void(^)(int))answer; @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Pitfall 1: Multithreading - (void) testCalculateSenseOfLife { Calculator* calculator = [[Calculator alloc]init]; [calculator calculateSenseOfLife:^(int answer) { XCTAssertEqual(answer, 23); }]; } ✔
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Code Diving Multithreading
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Pitfall 2: Umgang mit Abhängigkeiten ‣  Unit soll getestet werden ‣  Abhängigkeiten zu anderen „Units“ bestehen ‣  Lösung: Mocks statt realer Objekte
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action OCMock* ‣  Mocking Framework ‣  Täuscht Schnittstellen vor ‣  Deterministisches Verhalten * http://www.ocmock.org
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @interface Controller @property (weak, nonatomic) TwitterConnection* connection; @property (weak, nonatomic) IBOutlet TweetView* tweetView; - (void) displayTweets; @end @implementation Controller -(void) displayTweets { NSArray *tweets = [connection retrieveTweets]; for (Tweet t in tweets) { [self.tweetView addTweet:t]; } @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @implementation ControllerTests - (void)testDisplayTweets { Controller* controller = [[Controller alloc] init]; id connection = [OCMockObject mockForClass:[TwitterConnection class]]; controller.connection = connection; Tweet *testTweet = /* create a tweet somehow */; NSArray *tweetArray = [NSArray arrayWithObject:testTweet]; [[[connection stub] andReturn:tweetArray] displayTweets]; } @end Stubs
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action @implementation ControllerTests - (void)testDisplayTweets { ... id view = [OCMockObject mockForClass:[TweetView class]]; controller.tweetView = view; [[view expect] addTweet:testTweet]; [controller displayTweets]; [view verify]; } @end Expect & Verify
  • Und jetzt? Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action UI Automation
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Was ist UI Automation? ‣  JavaScript ‣  Integriert in Instruments ‣  benötigt Accessibility Features ‣  On-Device und Simulator
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action UIAElement ‣  Basisklasse für alle UI Elemente ‣  Name ‣  Value ‣  Elements ‣  Parent
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Control Hierarchie ‣  Target Application UIATarget.localTarget().frontMostApp();!
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Control Hierarchie ‣  Target Application ‣  Main Window UIATarget.localTarget().frontMostApp()! .mainWindow();!
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Control Hierarchie ‣  Target Application ‣  Main Window ‣  View UIATarget.localTarget().frontMostApp()! .mainWindow().staticTexts()[0];!
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Control Hierarchie ‣  Target Application ‣  Main Window ‣  View UIATarget.localTarget().frontMostApp()! .mainWindow().buttons()["add"];!
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Interaktion UIATarget.localTarget().frontMostApp() .mainWindow().buttons()["add"].tap(); UIATarget.localTarget().frontMostApp() .mainWindow().textFields()[0].setValue("Hello"); UIATarget.localTarget().frontMostApp() .mainWindow().tableViews()[0] .scrollToElementWithPredicate("name beginswith ‘Foo’");
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Timeouts UIATarget.localTarget().pushTimeout(2); UIATarget.localTarget().popTimeout(); UIATarget.localTarget().delay(2);
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Lifecycle var testName = "do something"; UIALogger.logStart(testName); ... if (testPassed){ UIALogger.logPass(testName); } else { UIALogger.logFail(testName); }
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Debugging UIALogger.logMessage("I am here!"); UIATarget.localTarget() .logElementTree(); UIATarget.localTarget() .captureScreenWithName("Screenshot-001");
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action Assertions #import "lib/tuneup_js/tuneup.js test("Checking label text", function(target, app) { var labelText = app.mainWindow().staticTexts()[0].value(); assertEquals(labelText, "Hello World"); }); http://www.tuneupjs.org
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 UI Automation in Action test("my test", function(target, app) { assertWindow({ tableViews: [ { groups: [ { name: "First Name" }, { name: "Last Name" } ], cells: [ { name: "Fred" }, { name: "Flintstone" } ] } ]}); });
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Code Diving UI Automation
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF in Action KIF – Keep It Functional https://github.com/kif-framework/KIF
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF in Action KIF – Keep It Functional ‣  Objective-C ‣  KIFTestCase : XCTestCase ‣  Integration in XCode ‣  Test Navigator ‣  Debugging
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF in Action KIFUITestActor ‣  als tester in jedem KIFTestCase ‣  „tap this view“ ‣  „enter text into this view“ ‣  „wait for this view“
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF in Action Installation via Cocoapods target 'CalculatorTests', :exclusive => true do pod 'KIF', '~> 3.0' end pod install
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF in Action @implementation CalculatorUiTests - (void) testAdd { [tester tapViewWithAccessibilityLabel:@"one"]; [tester tapViewWithAccessibilityLabel:@"add"]; [tester tapViewWithAccessibilityLabel:@"two"]; [tester tapViewWithAccessibilityLabel:@"equal"]; UILabel* display = (UILabel*)[tester waitForViewWithAccessibilityLabel:@"display"]; XCTAssertEqualObjects(display.text, @"3", @"result should be 3"); } @end
  • Go for Quality - automatisiertes Testen in iOS MTD 2014 Tests in Action Code Diving Keep It Functional
  • UI Automation Keep it Functional Sprache Javascript Objective-C Accessibility ✔ ✔ XCode Integration ✖ ✔ Debugging ✖ ✔ Mocking ✖ ✔ Continuous Integration ✔ ✔ Maintainer Apple Community Go for Quality - automatisiertes Testen in iOS MTD 2014 KIF vs. UI Automation
  • One more thing ...
  • Social Media One more thing… Go for Quality - automatisiertes Testen in iOS MTD 2014 Broken Windows Theorie
  • Go for Quality - automatisiertes Testen in iOS Michael Kotten | open knowledge GmbH @michaelkotten @_openKnowledge