XCUITest interact with a Notification Banner.

2019-06-08 04:07发布

问题:

Is it possible in XCUITest to validate that a notification banner is sent to the screen?

I can add an accessibility identifier to the notification, but I am having a problem getting XCUITest to interact with it when the banner is ent to the screen. I know that XCUITest runs in a separate process from the app, but was wondeering if it was still possible to interact with the notification or is it beyond the scope of XCUITest?

Thanks,

回答1:

With Xcode 9 this is now possible. You can get access to other apps. That includes the springboard which contains the Notification banner.

XCUIApplication now has a new initializer that takes a bundle identifier as parameter. It gives you a reference to the app that uses that bundle identifier. You can then use the normal queries to access UI elements. Just like you did before with your own app.

This is a test that checks if a Local Notification is being displayed when the app is closed:

import XCTest

class UserNotificationUITests: XCTestCase {

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
    }

    func testIfLocalNotificationIsDisplayed() {
        let app = XCUIApplication()
        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")

        app.launch()

        // close app to trigger local notification
        XCUIDevice.shared.press(XCUIDevice.Button.home)

        // wait for the notification
        let localNotification = springboard.otherElements["USERNOTIFICATION, now, Buy milk!, Remember to buy milk from store!"]
        XCTAssertEqual(waiterResultWithExpectation(localNotification), XCTWaiter.Result.completed)
    }
}

extension UserNotificationUITests {
    func waiterResultWithExpectation(_ element: XCUIElement) -> XCTWaiter.Result {
        let myPredicate = NSPredicate(format: "exists == true")
        let myExpectation = XCTNSPredicateExpectation(predicate: myPredicate,
                                                      object: element)
        let result = XCTWaiter().wait(for: [myExpectation], timeout: 6)
        return result
    }
}

You can checkout the demo app including this test here

You can also test Remote Notifications with UITests. That's needs a bit more work, because you cannot directly schedule Remote Notifications from your code. You can use a service called NWPusher for that. I wrote a blogpost about how to test Remote Notifications with Xcode UITests and there also is a demo project on github.



回答2:

Not yet, unfortunately. XCUITest does not provide access to the notification bar. For almost every test case scenario you might come up with, Appium is a good alternative, however Apple still does not provide means to test push notifications. One way to work around this is to force your app to send the notification, take a screenshot when the notification popup is being displayed and then use an image recognition technique to verify if the notification is correct (such as OpenCV). This is waaaaay more "workaround" then I would like to use, but is the only available method I know so far, hope this helps.