2. About Us
• Nadia Lin
• Software Engineer in Test in the KKBOX Inc
• Computer vision (openCV)
• Mark Chang
• Software Engineer in Test in the KKBOX Inc
• 🐴 的學習筆記 Blog
• Github markchangjz
8. Cases in automation test
class UITests: XCTestCase {
let app = XCUIApplication()
func testChatWithPeople() {
app.buttons["Home"].tap()
app.cells["Nadia"].tap()
app.textFields["Your message"].typeText("Hello")
XCTAssertTrue(……)
}
}
Case 1:
Home → Chat with people → Say “Hello”
9. Cases in automation test
class UITests: XCTestCase {
let app = XCUIApplication()
func testDeleteMessage() {
app.buttons["Home"].tap()
app.cells["Nadia"].swipeLeft()
app.buttons["Delete"].tap()
XCTAssertTrue(……)
}
}
Case 2:
Home → Swipe to delete message
11. Modify your cases
class UITests: XCTestCase {
let app = XCUIApplication()
func testChatWithPeople() {
app.buttons[“My Messages"].tap()
app.cells["Nadia"].tap()
app.textFields["Your message"].typeText("Hello")
XCTAssertTrue(……)
}
}
Case 1:
My Messages → Chat with people → Say “Hello”
12. Modify your cases
class UITests: XCTestCase {
let app = XCUIApplication()
func testChatWithPeople() {
app.buttons[“My Messages"].tap()
app.cells["Nadia"].tap()
app.textFields["Your message"].typeText("Hello")
XCTAssertTrue(……)
}
}
Case 2:
My Messages → Swipe to delete message
13. class UITests: XCTestCase {
let app = XCUIApplication()
func testChatWithPeople() {
app.buttons["My Messages"].tap()
app.cells["Nadia"].tap()
app.textFields["Your message"].typeText("Hello")
XCTAssertTrue(……)
}
func testDeleteMessage() {
app.buttons["My Messages"].tap()
app.cells["Nadia"].swipeLeft()
app.buttons["Delete"].tap()
XCTAssertTrue(……)
}
}
Something wrong?
Hard to maintain
14. class UITests: XCTestCase {
let app = XCUIApplication()
func testChatWithPeople() {
app.buttons["My Messages"].tap()
app.cells["Nadia"].tap()
app.textFields["Your message"].typeText("Hello")
XCTAssertTrue(……)
}
func testDeleteMessage() {
app.buttons["My Messages"].tap()
app.cells["Nadia"].swipeLeft()
app.buttons["Delete"].tap()
XCTAssertTrue(……)
}
}
Hard to read
Something wrong?
34. Page Object Pattern
Chat Room
Page
send message
Home
Page
chat
back
People
Page
chat
go to people page
Search
Page
go to search page
search
go to search page
35. Strategies & Tricks
• Protocol Extensions
• Tab Bar
• Search Bar
• Generics
• Go Back
• Go To Different Page
44. Protocol Extensions
Chat Room
Page
send message
Home
Page
chat
back
People
Page
chat
go to people page
Search
Page
go to search page
search
go to search page
45. Protocol Extensions
final class HomePage: Page, MessengerTabBar, MessengerSearchBar {
// ...
}
final class GroupsPage: Page, MessengerTabBar, MessengerSearchBar {
// ...
}
final class MePage: Page, MessengerTabBar, MessengerSearchBar {
// ...
}
final class PeoplePage: Page, MessengerTabBar, MessengerSearchBar {
// ...
}
54. Generics
func playPlaylistAndExpectTransitionToPage<T: Page>(type: T.Type) -> T {
//…
playButton.tap()
return type.init()
}
Possible 1. Go to Nowplaying page
chartPage.playPlaylistAndExpectTransitionToPage(NowplayingPage)
Possible 2. Go to Chart page
chartPage.playPlaylistAndExpectTransitionToPage(ChartPage)
56. Sets Element Accessibility
• Accessibility data makes UI testing possible
Reference: UI Testing in Xcode - WWDC 2015 - Videos - Apple Developer
Testability
Quality of Accessibility Data
57. Speed Up Testing
• Set launch arguments to speed up testing
Tutorial View
58. Speed Up Testing
override func setUp() {
//…
let app = XCUIApplication()
app.launchArguments.append("-forceDoNotShowTutorial")
app.launchArguments.append("1")
app.launch()
//…
}
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if ([standardDefaults boolForKey:@"forceDoNotShowTutorial"]) {
[UserConfig sharedInstance].everShowTutorial = YES;
}
• In Test Code (Swift 2.3) - Set launch arguments
• In App Code (Objective-C) - Read launch arguments
60. Reduce Motion
• Settings > General > Accessibility > Reduce Motion
• UIAccessibilityIsReduceMotionEnabled()
• Returns a Boolean value indicating whether
reduce motion is enabled (API Reference)
• true if the user has enabled Reduce Motion in
Settings; otherwise, false
64. Recap
• Make your page object at the user level,
rather than expose implement details
• Protocol Extensions: Extract common actions
• Generics: Go to indicated page
• iOS-Messenger-Page-Object
69. Q & A
• Q: (Hanyu) 因為我也有寫 UI testing,我⼀直很好奇⼀點就是,因為 UI testing 不能
在 Jenkins 上跑,它要在 Mac server 上跑,請問你們怎麼解決這個問題?
• A: (Zonble) 我們在 Mac server 上跑。
• Q: (Hanyu) 可是這樣⼦你們就,我不知道怎麼串接、那個架構是怎麼樣,我滿好奇的,
因為我知道你們好像是⼀台 Jenkins 然後掛 4、5 台 Mac server 吧。
• A: (Zonble) iOS team 的 Jenkins 跟 QA team 其實分開,有分開來的機器,然後兩個
部⾨間再互相 sync。你在我們部落格看到的我那篇⽂章講我們⾃⼰的 build system,然
後我們會 build ... 那台機器在 iOS team 這邊主要在 build 出 daily build,幾乎我們
RD 每個 branch 都有編出⾃⼰的,幾乎每個 revision 都編出⼀個版本,然後同時在執
⾏,像我們整個 app 有 4、5 個⾯向,app 裡頭的播放器、跟 server 的溝通,那邊寫
了⼀⼤堆的單元測試,在 Jenkins 上我們主要跑這些,那今年轉到 XCUITest 那
Jeremy 他們就 study 這些,看起來那個 Jenkins 跑這個東西就是跑得不順,就另外再
去架了那個 Xcode Server。然後 Xcode Server 就定時去拉新的 code 然後在上⾯執
⾏。
70. Reference
• Page Object
• DSL, Page Object and Selenium – a way to reliable functional tests
• Best Practices - SELENIUM DOCUMENTATION
• PageObjects · SeleniumHQ_selenium Wiki · GitHub
• XCUITest
• UI Testing Cheat Sheet and Examples · masilotti.com
• XCTest and the Page Object Model
• Swift
• Getting Started with Swift