Hello. I've been struggling to make some simple (and some not that simple) UI tests for iOS with the UITesting (XCUI) framework. While I've found the lack of official documentation a bit disturbing, a more serious hurdle has been .tap() not triggering the button action. I have enough experience in coding not to blame the frameworks (especially those of major player such as Apple) but I cannot see where the flaw in my setup is as I have read dozens of similar samples on the internet. So in a nutshell my problem is: calling app.buttons["foo"].tap() occasionally does not trigger the button action. If I clean out stuff under DerivedData, make a Clean and restart everything, it works once or twice and then starts failing 100% again. Please find my test case below:
import XCTest
class UITestPocUITests: XCTestCase {
var app: XCUIApplication!
func waitForElementToExist(element: XCUIElement, seconds waitSeconds: Double) {
let exists = NSPredicate(format: "exists == true")
expectationForPredicate(exists, evaluatedWithObject: element, handler: nil)
waitForExpectationsWithTimeout(waitSeconds, handler: nil)
}
func waitForLabelValue(element: XCUIElement, value: String, seconds waitSeconds: Double) {
let exists = NSPredicate(format: "label == %@", value)
expectationForPredicate(exists, evaluatedWithObject: element, handler: nil)
waitForExpectationsWithTimeout(waitSeconds, handler: nil)
}
override func setUp() {
super.setUp()
/
continueAfterFailure = false
/
app = XCUIApplication()
app.launch()
/
}
override func tearDown() {
/
super.tearDown()
/
app.terminate()
app = nil
}
func testShowMessage() {
/
/
/
let button = app.buttons["SHOW MESSAGE"]
print("exists = \(button.exists), hittable = \(button.hittable)")
app.buttons["SHOW MESSAGE"].tap()
let messageLabel = app.staticTexts["messageLabel"]
waitForLabelValue(messageLabel, value: "This is a message", seconds: 3.0)
/
/
/
/
/
/
}
func testDealloc() {
/
app.buttons["SHOW SECOND"].tap()
let navBar = app.navigationBars["Items"]
waitForElementToExist(navBar, seconds: 3)
let expectation = expectationWithDescription("Second view controller must have been deallocated")
let ipc = SimpleIPC()
ipc.listen { message in
print("Got message: \(message)")
if message == "SecondViewController.deinit" {
print("Second view controller deinitialized - expectation fulfilled!")
expectation.fulfill()
}
}
/
/
navBar.buttons["First"].tap()
waitForExpectationsWithTimeout(5) { error in
print("Error: \(error)")
}
}
}I've been running this under Xcode 9.3.1, iOS simulator, deployment target: iOS 9.3.
- Matti