Go for Quality - automatisiertes Testen in iOS

59
Go for Quality - automatisiertes Testen in iOS Michael Kotten | open knowledge GmbH @michaelkotten @_openKnowledge

description

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!

Transcript of Go for Quality - automatisiertes Testen in iOS

Page 1: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS Michael Kotten | open knowledge GmbH @michaelkotten

@_openKnowledge

Page 2: Go for Quality - automatisiertes Testen in iOS

MTD 2014

„Chuck Norris can unit test

entire applications with a single

assert.“

Facts of the day Go for Quality - automatisiertes Testen in iOS

Page 3: Go for Quality - automatisiertes Testen in iOS

Warum testen?

Go for Quality - automatisiertes Testen in iOS MTD 2014

Motivation

Page 4: Go for Quality - automatisiertes Testen in iOS

„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

Page 5: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Motivation

„Unit testing is not about finding bugs.“

Page 6: Go for Quality - automatisiertes Testen in iOS

‣  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

Page 7: Go for Quality - automatisiertes Testen in iOS

Wie testen?

Go for Quality - automatisiertes Testen in iOS MTD 2014

Motivation

Page 8: Go for Quality - automatisiertes Testen in iOS

eXtreme Clicking

Go for Quality - automatisiertes Testen in iOS MTD 2014

Motivation

Page 9: Go for Quality - automatisiertes Testen in iOS

nur auf dem Entwicklerrechner

Motivation Go for Quality - automatisiertes Testen in iOS

MTD 2014

Page 10: Go for Quality - automatisiertes Testen in iOS

Kunden

Motivation Go for Quality - automatisiertes Testen in iOS

MTD 2014

Page 11: Go for Quality - automatisiertes Testen in iOS

Motivation Go for Quality - automatisiertes Testen in iOS

MTD 2014

Expect the Unexpected!

Page 12: Go for Quality - automatisiertes Testen in iOS

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

Page 13: Go for Quality - automatisiertes Testen in iOS

Was testen?

Go for Quality - automatisiertes Testen in iOS MTD 2014

Motivation

Page 14: Go for Quality - automatisiertes Testen in iOS

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)

Page 15: Go for Quality - automatisiertes Testen in iOS

Gute Tests ... ‣ … treffen Annahmen nur einmal ‣ … sind isoliert ‣ … laufen unabhängig ‣ … sind vorhersehbar

Motivation Go for Quality - automatisiertes Testen in iOS

MTD 2014

Page 16: Go for Quality - automatisiertes Testen in iOS

Unit Test ‣  Testen der korrekten Funktionsweise

einzelner, isolierter Komponenten

‣  Automatisiert ‣  Wiederholbar

Motivation Go for Quality - automatisiertes Testen in iOS

MTD 2014

Page 17: Go for Quality - automatisiertes Testen in iOS

Tests in Action Go for Quality - automatisiertes Testen in iOS

MTD 2014

Page 18: Go for Quality - automatisiertes Testen in iOS

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

Page 19: Go for Quality - automatisiertes Testen in iOS

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

Page 20: Go for Quality - automatisiertes Testen in iOS

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

Page 21: Go for Quality - automatisiertes Testen in iOS

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

Page 22: Go for Quality - automatisiertes Testen in iOS

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

Page 23: Go for Quality - automatisiertes Testen in iOS

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

Page 24: Go for Quality - automatisiertes Testen in iOS

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

Page 25: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Code Diving

CalculatorTests

Page 26: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Pitfall 1: Multithreading @interface Calculator : NSObject ... -(void) calculateSenseOfLife:(void(^)(int))answer; @end

Page 27: Go for Quality - automatisiertes Testen in iOS

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); }]; }

Page 28: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Code Diving

Multithreading

Page 29: Go for Quality - automatisiertes Testen in iOS

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

Page 30: Go for Quality - automatisiertes Testen in iOS

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

Page 31: Go for Quality - automatisiertes Testen in iOS

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

Page 32: Go for Quality - automatisiertes Testen in iOS

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

Page 33: Go for Quality - automatisiertes Testen in iOS

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

Page 34: Go for Quality - automatisiertes Testen in iOS

Und jetzt?

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Page 35: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

UI Automation

Page 36: Go for Quality - automatisiertes Testen in iOS

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

Page 37: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

UI Automation in Action

UIAElement ‣  Basisklasse für alle UI Elemente ‣  Name ‣  Value ‣  Elements ‣  Parent

Page 38: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

UI Automation in Action

https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef

Page 39: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

UI Automation in Action

Control Hierarchie ‣  Target Application

UIATarget.localTarget().frontMostApp();!

Page 40: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

UI Automation in Action

Control Hierarchie ‣  Target Application ‣  Main Window

UIATarget.localTarget().frontMostApp()!.mainWindow();!

Page 41: Go for Quality - automatisiertes Testen in iOS

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];!

Page 42: Go for Quality - automatisiertes Testen in iOS

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"];!

Page 43: Go for Quality - automatisiertes Testen in iOS

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’");

Page 44: Go for Quality - automatisiertes Testen in iOS

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);

Page 45: Go for Quality - automatisiertes Testen in iOS

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); }

Page 46: Go for Quality - automatisiertes Testen in iOS

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");

Page 47: Go for Quality - automatisiertes Testen in iOS

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

Page 48: Go for Quality - automatisiertes Testen in iOS

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" } ] } ]}); });

Page 49: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Code Diving

UI Automation

Page 50: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

KIF in Action

KIF – Keep It Functional

https://github.com/kif-framework/KIF

Page 51: Go for Quality - automatisiertes Testen in iOS

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

Page 52: Go for Quality - automatisiertes Testen in iOS

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“

Page 53: Go for Quality - automatisiertes Testen in iOS

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

Page 54: Go for Quality - automatisiertes Testen in iOS

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

Page 55: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS MTD 2014

Tests in Action

Code Diving

Keep It Functional

Page 56: Go for Quality - automatisiertes Testen in iOS

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

Page 57: Go for Quality - automatisiertes Testen in iOS

One more thing ...

Page 58: Go for Quality - automatisiertes Testen in iOS

Social Media

One more thing… Go for Quality - automatisiertes Testen in iOS

MTD 2014

Broken Windows Theorie

Page 59: Go for Quality - automatisiertes Testen in iOS

Go for Quality - automatisiertes Testen in iOS Michael Kotten | open knowledge GmbH @michaelkotten

@_openKnowledge