简体   繁体   English

iOS-在UITests Target中使用推送通知

[英]iOS - Using Push Notifications in UITests Target

I am required to use push notifications in AppUITests. 我需要在AppUITests中使用推送通知。 Is there any way to add/update settings of a AppUITests target using custom entitlement file? 有什么方法可以使用自定义授权文件来添加/更新AppUITests目标的设置?

With Xcode 9 you can use Remote Notifications in your UITests by using a framework called NWPusher 使用Xcode 9,您可以通过使用名为NWPusher的框架在UITest中使用远程通知

To test Remote Notifications in your UITests you have to do the following steps: 要在UITest中测试远程通知,您必须执行以下步骤:

  1. Add NWPusher to your UITest target 将NWPusher添加到您的UITest目标
  2. Download a APN development certificate from Apple's Dev Center and add it to your Keychain (if it is not already there) 从Apple的开发中心下载APN开发证书,并将其添加到您的钥匙串中(如果尚不存在)
  3. Export the certificate as p12 file 将证书导出为p12文件
  4. Write the test 编写测试

I tried that out and this is my test file: 我尝试过了,这是我的测试文件:

My demo app presents three different modal view controllers depending on the push notification it receives. 我的演示应用程序根据收到的推送通知显示了三种不同的模式视图控制器。 So there are three different push notifications in this test. 因此,此测试中存在三种不同的推送通知。

import XCTest
import PusherKit

class PushNotificationUITests: XCTestCase {

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

    func testPushNotifications() {
        let app = XCUIApplication()
        app.launchArguments.append("isRunningUITests")
        app.launch()

        // access to the springboard (to be able to tap the notification later)
        let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")

        // dismiss the system dialog if it pops up
        allowPushNotificationsIfNeeded()

        // get the current deviceToken from the app
        let deviceToken = app.staticTexts.element(matching: .any, identifier: "tokenLabel").label

        // close app
        XCUIDevice.shared.press(XCUIDevice.Button.home)
        sleep(1)

        // trigger red Push Notification
        triggerPushNotification(
            withPayload: "{\"aps\":{\"alert\":\"Hello Red\"}, \"vcType\":\"red\"}",
            deviceToken: deviceToken)

        // tap on the notification when it is received
        springboard.otherElements["PUSHNOTIFICATION, now, Hello Red"].tap()

        // check if the red view controller is shown
        XCTAssert(app.staticTexts["Red"].exists)

        // dismiss modal view controller and close app
        app.buttons["Close"].tap()
        XCUIDevice.shared.press(XCUIDevice.Button.home)
        sleep(1)

        // trigger green Push Notification
        triggerPushNotification(
            withPayload: "{\"aps\":{\"alert\":\"Hello Green\"}, \"vcType\":\"green\"}",
            deviceToken: deviceToken)

        // tap on the notification when it is received
        springboard.otherElements["PUSHNOTIFICATION, now, Hello Green"].tap()

        // check if the green view controller is shown
        XCTAssert(app.staticTexts["Green"].exists)

        // dismiss modal view controller and close app
        app.buttons["Close"].tap()
        XCUIDevice.shared.press(XCUIDevice.Button.home)
        sleep(1)

        // trigger blue Push Notification
        triggerPushNotification(
            withPayload: "{\"aps\":{\"alert\":\"Hello Blue\"}, \"vcType\":\"blue\"}",
            deviceToken: deviceToken)

        // tap on the notification when it is received
        springboard.otherElements["PUSHNOTIFICATION, now, Hello Blue"].tap()

        // check if the blue view controller is shown
        XCTAssert(app.staticTexts["Blue"].exists)

        // dismiss modal view controller 
        app.buttons["Close"].tap()
    }
}

extension XCTestCase {
    func triggerPushNotification(withPayload payload: String, deviceToken: String) {
        let uiTestBundle = Bundle(for: PushNotificationUITests.self)
        guard let url = uiTestBundle.url(forResource: "pusher.p12", withExtension: nil) else { return }

        do {
            let data = try Data(contentsOf: url)
            let pusher = try NWPusher.connect(withPKCS12Data: data, password: "pusher", environment: .auto)
            try pusher.pushPayload(payload, token: deviceToken, identifier: UInt(arc4random_uniform(UInt32(999))))
        } catch {
            print(error)
        }
    }

    func allowPushNotificationsIfNeeded() {
        addUIInterruptionMonitor(withDescription: "“RemoteNotification” Would Like to Send You Notifications") { (alerts) -> Bool in
            if(alerts.buttons["Allow"].exists){
                alerts.buttons["Allow"].tap();
            }
            return true;
        }
        XCUIApplication().tap()
    }
}

I wrote a detailed blogpost about this and you can download the demo here 我写了一篇关于此的详细博客文章,您可以在此处下载演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM