Automated UI testing for iOS apps using KIF framework and Swift
-
Upload
jurgis-kirsakmens -
Category
Software
-
view
602 -
download
0
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/1.jpg)
USER INTERFACE
TESTING WITH KIF & SWIFT
![Page 2: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/2.jpg)
CASE FOR UI TESTINGINTEGRATION
NAVIGATION FLOWDATA FLOW
USER EXPERIENCEACCESSIBILITY
REFACTORINGS / REGRESSIONS
![Page 3: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/3.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/4.jpg)
![Page 5: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/5.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/6.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/7.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/8.jpg)
OBJECTIVE C [tester tapViewWithAccessibilityLabel:@"Login"];
SWIFT
tester().tapView(withAccessibilityLabel : "Login")
![Page 9: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/9.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/10.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/11.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/12.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/13.jpg)
FAST
NOT REALLY
![Page 14: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/14.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/15.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/16.jpg)
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](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/17.jpg)
![Page 18: Automated UI testing for iOS apps using KIF framework and Swift](https://reader031.fdocuments.us/reader031/viewer/2022013110/5881e3471a28ab36088b544d/html5/thumbnails/18.jpg)
UIAccessibility PROTOCOLUIAccessibilityElement CLASS
UIAccessibilityContainer PROTOCOL UIAccessibilityTraits
BUNDLED FREE WHEN USING UIKit, JUST SET
accessibilityLabel, accessibilityValue, accessibilityHint IN IB AND/OR CODE