我正在iOS应用程序中实现推送通知,正如我所做的那样,我想编写一个UI测试,用于验证应用程序在使用某个推送通知负载启动时是否正确(即应用程序导航)到正确的表视图并突出显示正确的单元格).
可以这样做吗?我似乎无法找到之前已经做过此事或曾经问过这个问题的人.
感谢任何指针.
解决方法
使用
Xcode 9,您现在可以在UITest中实际测试远程通知处理.我使用一个名为
NWPusher的框架实现了它
我写了一篇关于我的实现的长blogpost,并向github添加了一个演示项目.
以下是我所做的简短描述:
制备
>将NWPusher添加到您的UITest目标(我使用了Carthage)
>从Apple的开发中心下载适用于您的应用的APN开发证书
>在Keychain中打开该证书并将其导出为p12文件
>将此文件添加到IUTest目标
>使devicetoken可用于UITestRunner
写下测试
该测试执行以下步骤:
>创建对应用程序和Springboard的引用
>启动应用程序并通过点击主页按钮关闭它(如果弹出,则关闭系统对话框,询问是否允许)
>触发远程通知(使用NWPusher)
>从Springboard查询远程通知横幅并点按它
>测试您的应用是否正确处理了远程通知
>关闭应用程序并测试下一种类型的远程通知
在我的演示中,不同类型的通知会在应用程序中触发不同颜色的模态View Controller.所以我的测试类看起来像这样
import XCTest import PusherKit class PushNotificationUITests: XCTestCase { override func setUp() { super.setUp() continueAfterFailure = false } func testPushNotifications() { let app = XCUIApplication() app.launchArguments.append("isRunningUITests") let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard") app.launch() // 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\"}",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\"}",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() } }
这仅适用于物理设备,因为远程通知在模拟器中不起作用.