ui testing ios apps for humans - jakub turek · ui testing ios apps for humans jakub turek july 24,...

46
UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion

Upload: others

Post on 03-Jul-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

UI testing iOS apps for humans

Jakub TurekJuly 24, 2017

EL Passion

Page 2: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

About me

Jakub Turek

https://jakubturek.com @KubaTurek turekj

1

Page 3: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Agenda

1. Introduction to UI testing.2. Pain points.3. Apple’s built-in XCUITest.4. Snapshot tests with FBSnapshotTestCase.5. Interaction tests with EarlGrey.6. Combining snapshot & interaction testing.

2

Page 4: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Introduction to UI testing

Page 5: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Definition

UI Testing“UI testing gives you the ability to find and interact with the UIof your app in order to validate the properties and state of theUI elements.”Apple Developer

3

Page 6: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Motivation

Unit test UI testGrantee Developer End userInteracts Source code UI controls

- Code works as intended - Feature presenceProves - The API is simple - Correct output

- Proper layout

4

Page 7: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Writing a first UI test

Page 8: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Test case

Tap Animate progress Highlight

−→ −→

5

Page 9: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

UI testing problems (1/2)

What should I assert?

• Texts.• Icons.• Colors.• No progress bars.• Everything.

6

Page 10: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

UI testing problems (2/2)

When should I assert?

1. Wait & sleep.2. Tests failed.3. More wait & even more sleep.4. Tests succeeded.

7

Page 11: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

My initial impressions

Could we hire the Test AutomationEngineer, please?

8

Page 12: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

iOS built-ins

Page 13: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

A little bit of history

9

Page 14: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Automation quiz (1/2)

QuizHow Automation test cases were programmed?

10

Page 15: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Automation quiz (2/2)

AnswerUsing JavaScript, obviously.

var main = target.frontMostApp().mainWindow();var field = main.textFields()["Field"];

if (field.value() != "Input")UIALogger.logFail("Expected Field to have Input value");

elseUIALogger.logPass("Field has Input value");

11

Page 16: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

XCUITest

• Separate test target.• Swift & ObjC APIs forquerying UI elements.

• Black-box testing.• Two apps:

• app under test,• driver.

12

Page 17: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Test case reminder

Tap Animate progress Highlight

−→ −→

13

Page 18: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

XCUITest code

override func setUp() {super.setUp()XCUIApplication().launch()

}

func testNegativeAnswerHighlight() {let app = XCUIApplication()

app.staticTexts["Not really"].tap()

let ticked = app.staticTexts["x Not really"]let predicate = NSPredicate(format: "exists == 1")

expectation(for: predicate, evaluatedWith: ticked, handler: nil)waitForExpectations(timeout: 5.0, handler: nil)

}

14

Page 19: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

XCUITest issues (1/2)

Lots of „minor” issues:

• Super slow execution (≈ 10s startup penalty).• Fragile time-based expectations.• Type unsafe NSPredicate API.• Lack of communication with application sources:

• Passing launch arguments.

• Needs workaround for animations with .repeat option.

15

Page 20: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

XCUITest issues (2/2)

It is impossible to test the presented case.

protocol XCUIElementAttributes {var identifier: String { get }var frame: CGRect { get }var value: Any? { get }var title: String { get }var label: String { get }var elementType: XCUIElementType { get }var isEnabled: Bool { get }var horizontalSizeClass: XCUIUserInterfaceSizeClass { get }var verticalSizeClass: XCUIUserInterfaceSizeClass { get }var placeholderValue: String? { get }var isSelected: Bool { get }

}

16

Page 21: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Snapshot testing

Page 22: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Snapshot testing

Snapshot testingSnapshot testing compares rendered view to a “referenceimage” stored in the source code repository.

17

Page 23: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Snapshot testing workflow

Snapshot testing workflow is “different”:

1. Building a view:• This means no TDD.

2. Recording a reference snapshot.3. Assertion: comparing the view against the reference.

18

Page 24: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

FBSnapshotTestCase

facebook/ios-snapshot-test-case

FBSnapshotTestCase implements:

• Capturing reference snapshots.• Image comparison algorithm.• Visual diffing for expected/actual snapshots.

19

Page 25: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

FBSnapshotTestCase - example

class ViewControllerSnapshotTests: FBSnapshotTestCase {override func setUp() {super.setUp()recordMode = false // assertion, true for capturing

}

func testViewControllerHasCorrectView() {let sut = ViewController(nibName: nil, bundle: nil)sut.view.frame = UIScreen.main.bounds

FBSnapshotVerifyView(sut.view)}

}

20

Page 26: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Visual diff

Expected Got

Diff

21

Page 27: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Device agnostic snapshots

• The tests would fail if executed with different screensizes/densities.

• Device agnostic snapshots compare snapshots onmatching devices.

override func setUp() {super.setUp()isDeviceAgnostic = true // record/verify device agnosticrecordMode = true

}

22

Page 28: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Using FBSnapshotTestCase with Quick

ashfurrow/Nimble-Snapshots

describe("view") {it("has a valid snapshot") {let sut = ViewController(nibName: nil, bundle: nil)sut.view.frame = UIScreen.main.bounds

expect(sut.view).to(haveValidSnapshot()) // recordSnapshot()}

}

23

Page 29: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Use cases

Snapshot testing works great for enforcing correctness of:

• Localization & internationalization.• UI edge cases.• Layout for multiple devices, size classes.

24

Page 30: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Snapshot testing issues

Biggest pain points:

• TDD workflow is not possible.• Tests can go red even though the tested view looks asexpected.

25

Page 31: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Interaction testing with EarlGrey

Page 32: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

EarlGrey

EarlGreyiOS UI Automation testing framework from Google. It isinspired by Espresso for Android.

26

Page 33: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Key characteristics

Different approach than XCUITest:

• White-box testing:• Matchers work on arbitrary properties.• No need to set accessibility labels.

• Auto synchronization:• Assertions on a stable-state views only.• Expect/wait no more.• Synchronizes with networking, animations and operationsby default.

• Objective-C bridged API for Swift.

27

Page 34: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Example test (1/2)

−→log in

28

Page 35: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Example test (2/2)

func testLoginWorks() {EarlGrey.select(grey_kindOfClass(UITextField.self)).atIndex(0).perform(grey_typeText("12345"))

EarlGrey.select(grey_kindOfClass(UITextField.self)).atIndex(1).perform(grey_typeText("Username"))

EarlGrey.select(grey_buttonTitle("Log in")).perform(grey_tap())

EarlGrey.select(grey_text("Is UI testing easy?")).assert(grey_sufficientlyVisible())

}

29

Page 36: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Under the hood

Application state tracking is backed by solid reverseengineering and lots of method swizzling:

• CALayer→ setNeedsDisplay• NSURLConnection→sendAsynchronousRequest:queue:completionHandler:

• UIViewController→ viewWillAppear:• UIAnimation→ markStart:, markStop• Many more...

30

Page 37: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Fast animations

EarlGrey provides a simple API to speed up animations. Result:way faster suite execution.

class FeatureTests: XCTestCase {override func setUp() {super.setUp()GREYTestHelper.enableFastAnimation()

}}

31

Page 38: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Offscreen element matching

Scrolling down the table view.

func testMatchesOffScreenCell() {EarlGrey.select(grey_text("Cell Text"))

.using(grey_scrollInDirection(.down, 50.0),on: grey_kindOfClass(UITableView.self))

.assert(grey_sufficientlyVisible())}

32

Page 39: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Other features

Other interesting EarlGrey features are:

• Changing device orientation.• Layout assertions:

• Verifies conditions like: <ViewA> is to the left of <ViewB>.• Verbose API modelled after NSLayoutConstraint.

• Handles a plethora of interactions: tap, pinch, swipe, etc.• Rendering views to UIImage.

33

Page 40: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Issues

• Application state managed by hand:• EarlGrey test case cannot restart the application.

• No support for 3D-Touch.• EarlGrey cannot interact with system permission dialogs.• Asserting complete view hierarchy is painful.

34

Page 41: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

EarlGrey + snapshots = r

Page 42: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Test case

−→vote

35

Page 43: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Implementation

func testPositiveVoteWorks() {EarlGrey.select(grey_kindOfClass(SingleAnswerView.self))

.atIndex(1)

.perform(grey_tap())

.assert(grey_sufficientlyVisible())

EarlGrey.select(grey_kindOfClass(AnswerPicker.self)).assert(grey_verifyDeviceAgnosticSnapshot())

//.assert(grey_recordDeviceAgnosticSnapshot())}

36

Page 44: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

EarlGreySnapshots

elpassion/EarlGreySnapshots

Collection of snapshot assertions for EarlGrey. Key benefits:

• Asserting complete view hierarchies.• Visual failure diff instead of cryptic log messages.• Great technique to work with legacy code:

• Freezing a couple of critical paths is possible regardless ofthe code quality.

• Slightly faster feedback loop than without the tests at all.

37

Page 45: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Thank you

Thank you for yourattention!

38

Page 46: UI testing iOS apps for humans - Jakub Turek · UI testing iOS apps for humans Jakub Turek July 24, 2017 EL Passion. About me ... • Localization & internationalization. • UI edge

Further reading

Jakub TurekAutomated UI testing for iOS appshttps://jakubturek.com/automated-ui-tests-in-ios-apps/

Orta TheroxSnapshot Testinghttps://www.objc.io/issues/15-testing/snapshot-testing/

EarlGrey TeamGetting started with EarlGreyhttps://github.com/google/EarlGrey/

39