1 TIT10AIK @ WS 2012 Software-Engineering II Objektorientiertes Testen.
Go for Quality - automatisiertes Testen in iOS
-
Upload
open-knowledge-gmbh -
Category
Software
-
view
241 -
download
2
description
Transcript of Go for Quality - automatisiertes Testen in iOS
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