Error[8]: Undefined offset: 84, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

iOS模拟器发送通知和UI测试

背景

我们可能通过点击通知直接跳转到页面指定页面,或者点击通知打开web页面,更或者通过其他应用启动 app打开指定页面。面对这种跳转指定页面我们应该如何做 UI测试了?

向模拟器发送通知

从 Xcode11.4中,用户可以想 iOS 模拟器推送通知,包含以下两种方式:

终端使用 Xcode 命令执行,发送通知。将 apns 文件拖放到目标模拟器。 apns 文件

首先我们需要定义 apns 发送文件,并命名ExamplePush.apns

定义格式如下:

{
   "Simulator Target Bundle": "xxxx(包名)",

   "aps": {
       "badge": 0,
       "alert": {
           "title": "打开百度",
           "subtitle": "url加载测试",
           "body": "点击跳转App web 容器并且打开百度搜索",
       },
      "sound":"default",
   },
   "route": {
       "url":"https://www.baidu.com/"
   }
}

至此,你可以填写正确的应用包名,通过拖拽到模拟器来发送通知了。

Xcode 命令发送

在项目已经正确配置好通知所需要的条件后,保证待测模拟器的通知权限已经开启。

发送命令如下:

xcrun simctl push <device> com.example.my-app ExamplePush.apns

如命令所见,我们需要模拟器标识符,应用包名和 apns 文件。

同理,我们还可以通过xcrun simctl openurl booted 来发送通用链接和 scheme 跳转,请参考文章IOS Deep linking: URL Scheme vs Universal Links

获取模拟器设备标识符

应用包名

在结合之前我们定义的 apns 文件,发送通知的命令如下:

xcrun simctl push 942A6B1C-BE29-4E05-A075-5146088F7C9E com.compass.MusselExample PushNotificationTest.apns
UI 测试发送通知

可惜的是 XCodeTest 并没有提供在测试中发送通知的方式。

接下来该怎么办了?

方法1:【推荐】借助其他库实现,比如Mussel(可以在测试用例中发送通知、Scheme Link 和通用链接,最低支持 iOS11)、NWPush(配置麻烦,需要各种证书,教程示例)等库

方法2:自己写 shell 脚本和命令

使用 Mussel 发送通知

Mussel github 仓库:https://github.com/UrbanCompass/Mussel

自定义脚本发送通知

原理:在编译 UI测试 target 期间,添加运行脚本来发送通知

缺点:每次编译都会发送通知(需要手动控制参数)

编写推送通知脚本
#!/bin/bash
#推送和通用链接
#是否运行推送(以便关闭通知)1:打开 0关闭
isAllowPushNotification=1
# 获取脚本所在路径
DIR="$( cd "$( dirname ")"  &&" pwd )  #进入目录,以便发送 apns 文件" 
echo
${DIR} pushNotification

()# 模拟器 id{
    diviceId
    =# 应用包名xxxxx
    appName
    =$diviceIdxxxx
    xcrun simctl push $appName } ./ExamplePush.apns
if

[ $isAllowPushNotification == 1 ] ;then fi
pushNotification
chmod +x pushNotification.s

暂且命名为 pushNotification.sh 并把相应的权限修改了@interface OpentNotificationUITests : XCTestCase @property(nonatomic, strong) XCUIApplication *app; //当前应用 @property(nonatomic, strong) XCUIApplication *springboard; //系统页面 @end @implementation OpentNotificationUITests - (void)setUp { // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. self.continueAfterFailure = NO; // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. self.app = [[XCUIApplication alloc] init]; self.springboard = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; [self.app launch]; // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } (不然没有执行权限)。

UITest 添加运行脚本

将所需的脚本和 apns 文件都添加到测试 target 目录下后,选中UI 测试 target。 添加脚本。

这样每次编译 UI 测试 target 就会发送通知了。

打开通知页面的测试 *** 作

注意:我这里为了方便测试,关闭了通知以组显示的方式。

参数和setUp 方法

[+++]

测试方法

- (void)testOpenUrlFromNotification{
    [self openNotificationCenterTitle:@"打开百度"];
    NSArray *webViews = [[self.app webViews] allElementsBoundByIndex];  //业务中已处理(点击会通过 webViewController 去加载 url)
    XCTAssertTrue((webViews.count >= 1), @"应该打开 web 页面"); //  或者使用XCTAssertTrue([webViews[0] waitForExistenceWithTimeout:10], @"应该打开 web 页面");
}

辅助方法

我这里是通过通知的标题来获取对应通知,然后进行点击打开。

#pragma mark - helper
/// 相当于按  Home 键
- (void)toHome{
    [[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
}
/// 打开通知, 注意 需要保证模拟器通知方式[取消以组显示通知],通知 title 也需要不一致。
- (void)openNotificationCenterTitle:(NSString * _Nonnull)title {
    [self toHome];
    XCUIApplication *app = self.springboard;
    XCUICoordinate *coord1 = [app coordinateWithNormalizedOffset:CGVectorMake(0.1, 0.01)];
    XCUICoordinate *coord2 = [app coordinateWithNormalizedOffset:CGVectorMake(0.1, 0.8)];
    [coord1 pressForDuration:0.1 thenDragToCoordinate:coord2]; // 滑动显示通知
    
    
    XCUIElement *mainWindow = [[app windows] elementMatchingType:XCUIElementTypeWindow identifier:@"SBCoverSheetWindow"];
    NSArray *notiCells = [[mainWindow scrollViews] allElementsBoundByIndex];
    XCUIElement *scroll = notiCells[0];
    NSArray *allNotiCells = [[scroll scrollViews] allElementsBoundByIndex];
    
    XCUIElement *aimElement = nil;
    for (int i=0; i < allNotiCells.count; i++) {
        XCUIElement *cell = allNotiCells[i];
        NSLog(@"cellLabel:%@",cell.label);
        if ([cell.label containsString:title]) { // title = 打开百度 这里我是通过是否包含来找到某个通知。
            aimElement = cell;
            break;
        }
    }
    XCTAssertNotNil(aimElement,@"应该存在待测通知");
    [aimElement tap];
    
    XCUICoordinate *openCoordinate = [aimElement coordinateWithNormalizedOffset:CGVectorMake(0.2, 0.35)];
    [openCoordinate tap]; // 位置点击(模拟器通知 有 open按钮,相当点击了open)
}

消息点击效果

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 166, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
iOS模拟器发送通知和UI测试_app_内存溢出

iOS模拟器发送通知和UI测试

iOS模拟器发送通知和UI测试,第1张

iOS模拟器发送通知和UI测试

背景

我们可能通过点击通知直接跳转到页面指定页面,或者点击通知打开web页面,更或者通过其他应用启动 app打开指定页面。面对这种跳转指定页面我们应该如何做 UI测试了?

向模拟器发送通知

从 Xcode11.4中,用户可以想 iOS 模拟器推送通知,包含以下两种方式:

终端使用 Xcode 命令执行,发送通知。将 apns 文件拖放到目标模拟器。 apns 文件

首先我们需要定义 apns 发送文件,并命名ExamplePush.apns

定义格式如下:

{
   "Simulator Target Bundle": "xxxx(包名)",

   "aps": {
       "badge": 0,
       "alert": {
           "title": "打开百度",
           "subtitle": "url加载测试",
           "body": "点击跳转App web 容器并且打开百度搜索",
       },
      "sound":"default",
   },
   "route": {
       "url":"https://www.baidu.com/"
   }
}

至此,你可以填写正确的应用包名,通过拖拽到模拟器来发送通知了。

Xcode 命令发送

在项目已经正确配置好通知所需要的条件后,保证待测模拟器的通知权限已经开启。

发送命令如下:

xcrun simctl push <device> com.example.my-app ExamplePush.apns

如命令所见,我们需要模拟器标识符,应用包名和 apns 文件。

同理,我们还可以通过xcrun simctl openurl booted 来发送通用链接和 scheme 跳转,请参考文章IOS Deep linking: URL Scheme vs Universal Links

获取模拟器设备标识符

应用包名

在结合之前我们定义的 apns 文件,发送通知的命令如下:

xcrun simctl push 942A6B1C-BE29-4E05-A075-5146088F7C9E com.compass.MusselExample PushNotificationTest.apns
UI 测试发送通知

可惜的是 XCodeTest 并没有提供在测试中发送通知的方式。

接下来该怎么办了?

方法1:【推荐】借助其他库实现,比如Mussel(可以在测试用例中发送通知、Scheme Link 和通用链接,最低支持 iOS11)、NWPush(配置麻烦,需要各种证书,教程示例)等库

方法2:自己写 shell 脚本和命令

使用 Mussel 发送通知

Mussel github 仓库:https://github.com/UrbanCompass/Mussel

自定义脚本发送通知

原理:在编译 UI测试 target 期间,添加运行脚本来发送通知

缺点:每次编译都会发送通知(需要手动控制参数)

编写推送通知脚本
#!/bin/bash
#推送和通用链接
#是否运行推送(以便关闭通知)1:打开 0关闭
isAllowPushNotification=1
# 获取脚本所在路径
DIR="$( cd "$( dirname ")"  &&" pwd )  #进入目录,以便发送 apns 文件" 
echo
${DIR} pushNotification

()# 模拟器 id{
    diviceId
    =# 应用包名xxxxx
    appName
    =$diviceIdxxxx
    xcrun simctl push $appName } ./ExamplePush.apns
if

[ $isAllowPushNotification == 1 ] ;then fi
pushNotification
chmod +x pushNotification.s

暂且命名为 pushNotification.sh 并把相应的权限修改了@interface OpentNotificationUITests : XCTestCase @property(nonatomic, strong) XCUIApplication *app; //当前应用 @property(nonatomic, strong) XCUIApplication *springboard; //系统页面 @end @implementation OpentNotificationUITests - (void)setUp { // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. self.continueAfterFailure = NO; // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. self.app = [[XCUIApplication alloc] init]; self.springboard = [[XCUIApplication alloc] initWithBundleIdentifier:@"com.apple.springboard"]; [self.app launch]; // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } (不然没有执行权限)。

UITest 添加运行脚本

将所需的脚本和 apns 文件都添加到测试 target 目录下后,选中UI 测试 target。 添加脚本。

这样每次编译 UI 测试 target 就会发送通知了。

打开通知页面的测试 *** 作

注意:我这里为了方便测试,关闭了通知以组显示的方式。

参数和setUp 方法

 

测试方法

- (void)testOpenUrlFromNotification{
    [self openNotificationCenterTitle:@"打开百度"];
    NSArray *webViews = [[self.app webViews] allElementsBoundByIndex];  //业务中已处理(点击会通过 webViewController 去加载 url)
    XCTAssertTrue((webViews.count >= 1), @"应该打开 web 页面"); //  或者使用XCTAssertTrue([webViews[0] waitForExistenceWithTimeout:10], @"应该打开 web 页面");
}

辅助方法

我这里是通过通知的标题来获取对应通知,然后进行点击打开。

#pragma mark - helper
/// 相当于按  Home 键
- (void)toHome{
    [[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
}
/// 打开通知, 注意 需要保证模拟器通知方式[取消以组显示通知],通知 title 也需要不一致。
- (void)openNotificationCenterTitle:(NSString * _Nonnull)title {
    [self toHome];
    XCUIApplication *app = self.springboard;
    XCUICoordinate *coord1 = [app coordinateWithNormalizedOffset:CGVectorMake(0.1, 0.01)];
    XCUICoordinate *coord2 = [app coordinateWithNormalizedOffset:CGVectorMake(0.1, 0.8)];
    [coord1 pressForDuration:0.1 thenDragToCoordinate:coord2]; // 滑动显示通知
    
    
    XCUIElement *mainWindow = [[app windows] elementMatchingType:XCUIElementTypeWindow identifier:@"SBCoverSheetWindow"];
    NSArray *notiCells = [[mainWindow scrollViews] allElementsBoundByIndex];
    XCUIElement *scroll = notiCells[0];
    NSArray *allNotiCells = [[scroll scrollViews] allElementsBoundByIndex];
    
    XCUIElement *aimElement = nil;
    for (int i=0; i < allNotiCells.count; i++) {
        XCUIElement *cell = allNotiCells[i];
        NSLog(@"cellLabel:%@",cell.label);
        if ([cell.label containsString:title]) { // title = 打开百度 这里我是通过是否包含来找到某个通知。
            aimElement = cell;
            break;
        }
    }
    XCTAssertNotNil(aimElement,@"应该存在待测通知");
    [aimElement tap];
    
    XCUICoordinate *openCoordinate = [aimElement coordinateWithNormalizedOffset:CGVectorMake(0.2, 0.35)];
    [openCoordinate tap]; // 位置点击(模拟器通知 有 open按钮,相当点击了open)
}

消息点击效果

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/996685.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存