Mit dem Release von Xcode 7 hat sich einiges im Bereich Unit Testing getan. Neben Code Coverage wurde vor allem der Bereich UI Testing erweitert. Musste man früher noch UI-Tests per JavaScript schreiben und in Instruments laufen lassen, hat Apple heute das ungeliebte UI Automation Framework eingestampft und durch UI-Tests ersetzt, die in Swift geschrieben und direkt in Xcode ausgeführt werden. Dieser Vortrag stellt die Neuerungen vor und zeigt anhand eines Beispiels, was alles möglich ist.
3. #WISSENTEILEN
„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!“
UI Testing mit Xcode 7
MTC
2016
Motivation
13. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Motivation
„It makes no sense
to test something that
can’t be broken (or fixed)!“
(Zitat: alter weiser Mann)
14. #WISSENTEILEN
Gute Tests ...
‣… treffen Annahmen nur einmal
‣… sind isoliert
‣… laufen unabhängig
‣… sind vorhersehbar
Motivation
UI Testing mit Xcode 7
MTC
2016
15. #WISSENTEILEN
Unit Test
‣ Testen der korrekten Funktionsweise
einzelner, isolierter Komponenten
‣ Automatisiert
‣ Wiederholbar
Motivation
UI Testing mit Xcode 7
MTC
2016
16. #WISSENTEILEN
UI Test
‣ Wie Unit Test
‣ Fokus auf
‣ Event Handling (Tap, Swipe etc.)
‣ GUI Elemente
Motivation
UI Testing mit Xcode 7
MTC
2016
18. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Historie
Das war UI Testing vor Xcode 7
‣ UI Automation
‣ KIF - Keep it functional
‣ Frank
‣ Subliminal*
* wird nicht mehr weiterentwickelt
23. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Historie - KIF
KIF – Keep It Functional
‣ Objective-C
‣ Integration in Xcode
‣ Test Navigator
‣ Debugging
‣ Gray-Box-Test
‣ nutzt private API
24. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Historie - KIF
class CalculatorUiTests : KIFTestCase {
func testAdd() {
tester.tapViewWithAccessibilityLabel("one")
tester.tapViewWithAccessibilityLabel("add")
tester.tapViewWithAccessibilityLabel("two")
tester.tapViewWithAccessibilityLabel("equal")
XCTAssertEqual(display.text!, "3", "result should be 3")
}
}
38. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Übersicht
‣ Per Interface Builder
‣ Per API
func setValue(value: String) {
self.label.text = value
self.label.accessibilityValue =
value
}
40. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ XCUIDevice
‣ XCUIElementQuery
‣ XCUIElement
41. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ Einstieg in die App
override func setUp() {
super.setUp()
let app = XCUIApplication()
app.launch()
}
42. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ Einstieg in die App
‣ Startparameter steuern
override func setUp() {
super.setUp()
let app = XCUIApplication()
app.launchArguments = [ "TEST_MODE" ]
app.launchEnvironment = [ "animations" : "0" ]
app.launch()
}
43. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ Einstieg in die App
‣ Startparameter steuern
let testMode =
NSProcessInfo.processInfo().arguments.contains("TEST_MODE")
44. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ Einstieg in die App
‣ Startparameter steuern
if NSProcessInfo.processInfo().environment["animations"] == "0" {
UIView.setAnimationsEnabled(false)
}
45. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIApplication
‣ Einstieg in die App
‣ Startparameter steuern
let testMode =
NSProcessInfo.processInfo().arguments.contains("TEST_MODE")
46. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIDevice
‣ Zugriff auf „Hardware“
XCUIDevice.sharedDevice()
47. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIDevice
‣ Zugriff auf „Hardware“
‣ Device Orientation
XCUIDevice.sharedDevice().orientation = .LandscapeLeft
48. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIDevice
‣ Zugriff auf „Hardware“
‣ Device Orientation
‣ Hardware Buttons
XCUIDevice.sharedDevice().pressButton(.Home)
49. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElement
‣ Interaktion (z.B. tap() oder swipeUp())
XCUIApplication().buttons["five"].tap()
50. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElement
‣ Interaktion (z.B. tap() oder swipeUp())
‣ Sichtbarkeit mit exists
XCTAssert(XCUIApplication().buttons["five"].exists)
51. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElementQuery
‣ „Suche“ nach UI Elementen
app.tableViews[0].cells[0]
52. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElementQuery
‣ „Suche“ nach UI Elementen
app.tables.element.cells.elementAtIndex(0)
53. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElementQuery
‣ „Suche“ nach UI Elementen
app.tables.element.cells["cellIdentifier"]
54. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ XCUIElementQuery
‣ „Suche“ nach UI Elementen
‣ Ausführung erst bei Interaktion
‣ Fehler falls nicht eindeutig
app.tables.element.cells["cellIdentifier"].tap()
66. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
API
‣ Auf Elemente warten
let element = app.alerts["Timeout"]
let existsPredicate = NSPredicate(format: "exists == true")
expectationForPredicate(existsPredicate,
evaluatedWithObject: element, handler: nil)
waitForExpectationsWithTimeout(5, handler: nil)
68. #WISSENTEILEN
UI Automation Keep it Functional UI Testing
Sprache Javascript Objective-C/Swift Objective-C/Swift
Maintainer Apple Community Apple
Accessibility ✔ ✔ ✔
Xcode ✖ ✔ ✔
Debugging ✖ ✔ ✔
Mocking ✖ ✔ ✖
Continuous
Integration
✔ ✔ ✔
Zukunftssicher ✖ ✖ ✔
UI Testing mit Xcode 7
MTC
2016
KIF vs. UI Automation vs. UI Testing
69. #WISSENTEILEN
UI Testing mit Xcode 7
MTC
2016
Fazit
✓ Offizielle Lösung von Apple
✓ Kein JavaScript mehr
✓ Test recording
✓ Schnelligkeit
- Flexibilität