Automated UI testing for iOS apps using KIF framework and Swift

19
USER INTERFACE TESTING WITH KIF & SWIFT

Transcript of Automated UI testing for iOS apps using KIF framework and Swift

Page 1: Automated UI testing for iOS apps using KIF framework and Swift

USER INTERFACE

TESTING WITH KIF & SWIFT

Page 2: Automated UI testing for iOS apps using KIF framework and Swift

CASE FOR UI TESTINGINTEGRATION

NAVIGATION FLOWDATA FLOW

USER EXPERIENCEACCESSIBILITY

REFACTORINGS / REGRESSIONS

Page 3: Automated UI testing for iOS apps using KIF framework and Swift

UI TESTING IS HARD AND TIME CONSUMING

UNLESSAUTOMATED

EASY TO MAINTAIN FAST

Page 4: Automated UI testing for iOS apps using KIF framework and Swift
Page 5: Automated UI testing for iOS apps using KIF framework and Swift

NATIVE SUPPORT FOR UI TESTING

UI AUTOMATION (JavaScript)XCUI (Swift/Objective C)

BASED ON UIAcessibility PROTOCOL

Page 6: Automated UI testing for iOS apps using KIF framework and Swift

KIFKeep It Functional - An iOS Functional

Testing Framework

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

UICONF 2016 TALK BY ELLEN SHAPIRO https://youtu.be/hYCUy-9yq_M

Page 7: Automated UI testing for iOS apps using KIF framework and Swift

OBJECTIVE C - KIFTestCase RUNS IN APP TARGET

beforeAll, beforeEach, afterAll, afterEachKIFUITestActor - USER ACTIONS

KIFSystemTestActor - SYSTEM/DEVICE ACTIONS SWIFT - XCTestCase

ADD SIMPLE EXTENSION TO ACCESS KIFUITestActor AND KIFSystemTestActor

Page 8: Automated UI testing for iOS apps using KIF framework and Swift

OBJECTIVE C [tester tapViewWithAccessibilityLabel:@"Login"];

SWIFT

tester().tapView(withAccessibilityLabel : "Login")

Page 9: Automated UI testing for iOS apps using KIF framework and Swift

EXTENSIONS FOR READIBILITY extension KIFUITestActor {

@discardableResult func waitForButton(_ label: String) -> UIView! { let button = self.waitForTappableView(withAccessibilityLabel: label, traits: UIAccessibilityTraitButton)

return button }

func tapButton(_ accessibilityLabel: String, value: String) { let button = waitForButton(accessibilityLabel, value: value) button?.tap() }

}

RESULT

tester().tapButton(“Login”) // or even better – tester().tapLoginButton()

Page 10: Automated UI testing for iOS apps using KIF framework and Swift

PROTOCOL TO ACCESS APP DATA public protocol UsesCoreDataDatabase { func dbContext() -> NSManagedObjectContext func isDbEmpty(_ context: NSManagedObjectContext) -> Bool func deleteDbData(_ context: NSManagedObjectContext) }

public extension UsesCoreDataDatabase { func dbContext() -> NSManagedObjectContext { let appDelegate: YourAppDelegate = UIApplication.shared.delegate as! YourAppDelegate let context = appDelegate.value(forKey: "context") as! NSManagedObjectContext XCTAssertNotNil(context) return context! }

func isDbEmpty(_ context: NSManagedObjectContext) -> Bool { // access model objects from context let count = …. return (count == 0) }

func deleteDbData(_ context: NSManagedObjectContext) { // Delete data }

Page 11: Automated UI testing for iOS apps using KIF framework and Swift

CUSTOM TEST CASES class MyTestCaseWithEmptyDatabase: KIFTestCase, UsesCoreDataDatabase {

override func beforeEach() { let context = dbContext()

if ! sDbEmpty(context) { let name = MyAppServices.deviceModel() if name == "iPhone Simulator" { deleteDbData(context) } else { } // Are you sure want to delete data from device? }

} }

class MyTestCaseWithWizardFilled: MyTestCaseWithEmptyDatabase { var rentAmount = “100”; var unitName= “M10”; var tenantName = “Anna" override func beforeEach() { super.beforeEach() let context = dbContext() MyWizardController.saveFromWizard(in: context, address: unitName, tenant: tenantName amount: rentAmount) }

}

class MyTestCaseWithFixturesLoaded : MyTestCaseWithEmptyDatabase { // load fixture data in database

}

Page 12: Automated UI testing for iOS apps using KIF framework and Swift

DRY, READABLE TESTS class PaymentTests: MyTestCaseWithWizardFilled { func testAddPayment_fromUnitDashboard() {

// given - tenantName, unitName, today are defined as MyTestCaseWithWizardFilled class variables let amount = “5.1”; let paymentAmount = “$5.10”

tester().tapPropertiesTabButton() tester().tapUnit(unitName, tenant: tenantName) tester().waitForTenantBalanceScreen(tenantName, currentBalance: "$0.00") tester().waitForLastPaymentLine("No rent payments received", amount: “") // even this should be replaced by waitForNoLastPaymentLine // when tester().tapAddPaymentButton() tester().enterOnKeyboard(amount) tester().tapSaveButton() // then tester().waitForTenantBalanceScreen(tenantName, currentBalance: paymentAmount) tester().waitForLastRentPaymentLine(today, amount: paymentAmount)

} } … public extension KIFUITestActor { /// Returns last payment line in rental unit dashboard @discardableResult func waitForLastPaymentLine(_ date: String, amount: String) -> UIView! { let view = waitForView("Last rent payment", value: "\(date), \(amount)”) // Accessibility label & accessibility value return view } }

Page 13: Automated UI testing for iOS apps using KIF framework and Swift

FAST

NOT REALLY

Page 14: Automated UI testing for iOS apps using KIF framework and Swift

MAKE UI TESTS FASTERclass MyTestCaseWithEmptyDatabase: KIFTestCase, UsesCoreDataDatabase { override func beforeAll() { UIApplication.shared.keyWindow!.layer.speed = 100; // faster animations } }

Page 15: Automated UI testing for iOS apps using KIF framework and Swift

GOTCHAS & HINTSOCCASIONALLY CAN FAIL WITHOUT A GOOD REASON

¯\_( )_/¯

BEWARE OF UITableViewCellsADD EVERYTHING AS SUBVIEW TO .contentView

SAVE SCREENSHOTS ON TEST FAILURESET ENV VARIABLE WITH FOLDER LOCATION- KIF_SCREENSHOTS= …

AFTER FAILING TEST IN MODAL VIEW ALL OTHER TEST RESULTS = USELESS

do { try tester().trySomething(); // then test } catch {}

Page 16: Automated UI testing for iOS apps using KIF framework and Swift

ACCESSIBILITYhttps://youtu.be/no12EfZUSQo

“You have no clue about your app accessibility until you write app UI tests

that rely on accessibility” / me to myself /

Page 17: Automated UI testing for iOS apps using KIF framework and Swift
Page 18: Automated UI testing for iOS apps using KIF framework and Swift

UIAccessibility PROTOCOLUIAccessibilityElement CLASS

UIAccessibilityContainer PROTOCOL UIAccessibilityTraits

BUNDLED FREE WHEN USING UIKit, JUST SET

accessibilityLabel, accessibilityValue, accessibilityHint IN IB AND/OR CODE

Page 19: Automated UI testing for iOS apps using KIF framework and Swift

QUESTIONS?

Jurģis Ķiršakmens [email protected] @jki / @xjki