Search code examples
swiftiphonetestingxcuitest

XCUITest verify that ui interruption handler occurred


I'm very new to swift and xcuitest. I recently came across addUIInterruptionMonitor for handling alerts that can pop up. What I would like to know is how I can verify that the alert happened and that the handler was dealt with. Take the following for example

addUIInterruptionMonitorWithDescription("Location Services") { 
  (alert) -> Bool in
  alert.buttons["Allow"].tap()
  return true
}

app.buttons["Request Location"].tap()
app.tap() // need to interact with the app again for the handler to fire
// after this if the handler never gets called I want the test to fail

I would like to test that the alert actually happens, but as far as I understand, after my last tap() if the alert never gets triggered my handler wont be called. I need to test that the alert actually happened and then maybe add some assertions to the contents of the handler


Solution

  • I seem to have answered my own question on further investigation. For asynchronous testing with xcuitest I can use a XCTestExpectation which will when created, cause the test to wait until the expectation is fulfilled, or fail after a certain timeout. With that my above code becomes:

    let expectation = XCTestExpectation(description: "Location Service Alert")
    
    let locationMonitorToken = addUIInterruptionMonitorWithDescription("Location Services") { 
      (alert) -> Bool in
      alert.buttons["Allow"].tap()
      expectation.fulfill() // test waits for this before passing
      return true
    }
    
    app.buttons["Request Location"].tap()
    app.tap() // alert triggered here
    wait(for: [expectation], timeout: 3.0)
    removeUIInterruptionMonitor(locationMonitorToken)
    

    Update: forgot to put in the wait(for: [expectation], timeout: 3.0) after alert triggered to ensure handler is called.