Xcode 9的动手XCUITest功能

注意:本文最初发布在我的个人博客上。 继续阅读此处,因为某些GIF尚未上传到Medium。

在WWDC 2017上,有一个关于“测试中的新增功能”的精彩会议,主要讨论XCTest和XCUITest框架的新功能。 苹果公司开发人员工具团队在使用XCUITest进行UI测试以及与Xcode Server进行持续集成方面进行了重大改进。 在本文中,我们将通过Xcode 9和命令行中的实际示例探索所有新功能。 探索过程中创建了Github存储库Xcode9-XCTest。 您可以将这篇文章引用到该GitHub存储库,以自己尝试一下。

宣布了许多与针对Apple平台(尤其是iOS和macOS)的测试有关的新事物。 其中一些如下。

  • XCUISiriService
  • 本地化测试
  • 异步测试
  • UI测试性能改进
  • 活动,附件和屏幕截图
  • 多应用测试
  • xcodebuild:无头测试
  • xcodebuild:并行测试
  • 内置Xcode服务器

测试过程中有很多增强功能,包括Siri集成,XCTest中的Waiting,xcodebuild中的Core Simulators等。 让我们一一介绍。

XCUISiriService

使用XCUISiriService,我们现在可以与Siri界面进行交互。 我们可以通过传递来自XCUITests的语音识别文本来控制Siri,Siri将采取相应的行动。 想象一下,我们想使用XCUISiriService打开一个Apple News应用程序,我们可以从测试中做到这一点。

  func testXCUISiriService(){ 
XCUIDevice()。siriService.activate(voiceRecognitionText:“打开新闻”)
}

几个月前,当我与Xcode 8.3一起宣布使用XCUISiriService从XCTest控制Siri时,我写了一个详细的博客,它还在Github XCUISiriServiceDemo上创建了演示项目,但API语法有所变化,但示例仍然有效。

实际例子

在Xcode 9中打开Xcode9-XCTest项目,然后从Xcode9_XCTestUITests.swift文件运行testXCUISiriService()测试。 您可以看到Siri将打开Apple News应用程序。

本土化

使用Xcode 9,我们可以使用Xcode方案在不同的Language和Region中运行测试。 在编辑方案时,我们会看到“测试”选项,以使用特定的语言和区域运行测试。 通过更改方案设置,我们可以轻松地用不同的语言和地区测试我们的应用程序。

异步测试

在很多情况下,我们需要等到事情发生以进行测试执行为止,例如打开文档,等待服务器的响应等,但这在UI测试场景中最常见。 到目前为止,XCTest通过创建期望来处理异步测试,并且测试将一直等到期望得到满足。 XCTest超时将导致测试失败。 期望与XCTestCase紧密相关。

现在,XCTest具有新的类XCTWaiter,它使我们可以显式定义与XCTestCase分离的期望。 它具有作为公共API的初始化程序,然后涵盖了不同的等待条件。 XCTWaiter等待一组期望被实现。 我们现在可以这样定义期望:

 等待(用于:[documentExpectation],超时:10) 
// 要么
XCTWaiter(delegate.self).wait(用于:[documentExpectation],超时:10)
// 要么
让结果= XCTWaiter.wait(用于:[documentExpectation],超时:10)
如果结果==。timeout {
...
}

新添加的类和子类的列表如下:

  • XCTWaiter:控制等待策略。
  • XCTNSPredicateExpectation:编写自动化测试时可读的期望
  • XCTKVOExpectation:编写自动化测试时可读的期望
  • XCTDarwinNotificationExpectation:另一个可读的通知期望。

还有一个方便的API,我们可以用来等待XCUIElement的存在。

  XCUIElement.waitForExistance() 

实际例子

在Xcode 9中打开Xcode9-XCTest项目,然后从Xcode9_XCTestUITests.swift文件运行testXCWaiterfeatures()测试。 几个月前,我已经在XCWaiter的Swift中进行了关于异步iOS测试的详细文章,在GitHub上也有演示项目。

UI测试性能改进

删除快照

我们知道,XCUIApplication是与主应用程序交互的代理应用程序,用于启动,终止和查询主应用程序。 苹果使用快照工具在XCUI应用程序和主应用程序之间进行通信,这导致了时间和内存方面的性能问题。 现在,快照已被删除,并由远程查询和查询分析技术代替,以提高XCUItests的性能。 我们可能会更快地执行测试。

首次比赛API

苹果还推出了First Match API,以加快查询响应速度。 找到第一个XCUIElement而不是查询所有内容后,First Match API会提早退出。 我们可以在任何XCUIElement上使用firstMatch

 让按钮= app.navigationBars.buttons [“完成”] .firstMatch 

现在查询将具有更快的幅度并且没有内存峰值。

比赛第一对所有比赛

  app.buttons.firstMatch //不好的主意 
  app.buttons [“ Done”]。firstMatch //更好 
  app.navigationsBars.buttons [“完成”] .firstMatch //最佳 

活动,附件和屏幕截图

在组织可读报告的测试,截取XCUIElement的屏幕快照以及将丰富的数据附加到测试报告方面,有了很大的改进。 今年引入了三种不同的概念,分别是

  • 活动:通过赋予有意义的名称来对动作进行分组
  • 屏幕截图:全屏或特定XCUIElement的屏幕截图
  • 附件:将丰富的数据附加到XCTest报告。

活动项目

UI测试通常是长期运行的,并且在那里发生许多动作,例如,点击按钮,滑动等。到目前为止,XCTest报告显示了测试报告中的所有动作,这些动作不是特别可读。 活动是通过提供有意义的名称将这些操作分组的方式,因此XCTest结果将在结果中使用该活动名称以使其更具可读性。 您可以在此处阅读有关Apple官方文档的更多活动。
我们可以将活动分散到任何一组操作上,例如以干净状态启动应用程序

  XCTContext.runActivity(名称:“鉴于我已经以干净状态启动了应用程序”) 
XCUIApplication()。launch()
XCUIApplication()。launchArguments = [“ -StartFromCleanState”,“ YES”]
}

现在,我们已经定义了在干净状态下启动应用程序的活动。 当我们运行测试时,然后在测试报告中,我们会看到“鉴于我已以干净状态启动了应用程序”,因此更具可读性。 我们仍然可以通过扩展活动来访问基本操作。

屏幕截图

苹果还宣布了新的API,将全屏截图和特定的XCUIElements截图。 有一个新协议XCUIScreenshotProviding提供当前UI状态的屏幕截图,还有两个新类XCUIScreen和XCUIScreenshot来捕获应用程序或UIElement状态的屏幕截图。 我们可以使用以下代码片段获取屏幕截图。

 让屏幕= XCUIScreen.main 
让fullscreenshot = screen.screenshot()

附件

附件可用于将丰富的数据附加到测试报告。 它可能是来自测试的数据,改进的分类分类附加日志,后处理工作流程。 数据可以采用原始二进制数据,字符串,属性列表,代码对象,文件或图像的形式。 我们可以使用附件将屏幕快照附加到活动。 我们可以向活动添加附件,如下所示:

  XCTContext.runActivity(named:“当我向活动添加附件时”){(活动) 
让屏幕= XCUIScreen.main
让fullscreenshot = screen.screenshot()
let fullScreenshotAttachment = XCTAttachment(屏幕截图:fullscreenshot)
fullScreenshotAttachment.lifetime = .keepAlways
activity.add(fullScreenshotAttachment)
}

实际例子

在Xcode 9中打开Xcode9-XCTest项目,然后从Xcode9_XCTestUITests.swift文件运行testActivitiesScreenShotsAttachments()测试。 您可以看到Xcode中的测试报告采用的是活动名称,而不是操作。 在其他测试中,我们将屏幕快照附加到该活动。

在此处观看GIF动画

多应用测试

以前,我们只能测试一个应用程序,它是XCUITest目标的目标应用程序。 无法与XCUITest的其他应用程序(如“设置”或“新闻”)进行交互。 XCUIApplication()用于启动,终止和查询被测应用程序。 它只能访问被测目标应用程序,而不能测试其他应用程序。 始终需要访问其他应用程序,例如设置或应用程序扩展。

使用Xcode 9,我们可以使用XCUIApplication测试多个应用程序。 它具有三个主要更改,现在是XCUIApplication()

  • 有带有bundleIdentifier的初始化程序,以便我们可以传递应用程序的bundleID
  • 具有新的activate()方法可从后台激活应用
  • 有国家监督申请的变化。 各州都有如runningBackground,runningForeground等情况

我们可以使用以下代码在一个XCTest中测试两个应用程序

  func testTwoApps(){ 
让app1 = XCUIApplication(bundleIdentifier:“ com.app1.xyz”)
让app2 = XCUIApplication(bundleIdentifier:“ com.app2.xyz”)
//启动App1
app1.launch()
//启动并测试App 2
app2.launch()
app2.launchArguments = [“ -StartFromCleanState”,“ YES”]
//通过从后台激活App1再次对其进行测试
app1.activate()
}

activate()方法会自动等待另一个应用程序被激活,但是在某些情况下,我们希望通过使用谓词和XCUIApplication状态来手动等待应用程序被激活。

 让app1ActiveExpectation = XCTNSPredicateExpectation(谓词:NSPredicate(格式:“ state == \(XCUIApplication.State.runingForeground.rawValue”),对象:app1) 
 等待(用于:[app1ActiveExpectation],超时:10) 

如我们所见,只要我们知道捆绑包标识符,就可以与Simulator或设备中的任何应用进行交互。 这是对iOS应用程序的UI测试的巨大改进。

实际例子

在Xcode 9中打开Xcode9-XCTest项目,然后从Xcode9_XCTestUITests.swift文件运行testMultipleApps()测试。 我们正在与主应用程序和设置应用程序进行交互。

注意:目前在启动设置时测试失败,但无论如何模拟器都在启动设置应用程序。请 在此处 观看GIF

xcodebuild:无头测试

xcodebuild命令行工具有一些巨大的改进,该工具用于分析,构建,测试和归档iOS应用程序。 xcodebuild将使用核心模拟器来运行测试,因此从命令行运行测试时,我们看不到模拟器在运行。 这意味着我们不会在CI服务器上看到模拟器。 它将完全没有头。

实际例子

克隆或下载Xcode9-XCTest项目并运行xcodebuild命令。 需要注意的一件事是,在运行测试时不会启动模拟器。

  $ git clone https://github.com/Shashikant86/Xcode9-XCTest 
$ cd Xcode9-XCTest
$ xcodebuild -scheme“ Xcode9-XCTest” -destination'platform = iOS Simulator,name = iPhone 7 Plus,OS = 11.0'构建测试CODE_SIGN_IDENTITY =“” CODE_SIGNING_REQUIRED = NO

xcodebuild:并行测试

xcodebuild支持并行设备测试。 这意味着只要配置了设备,我们就可以在多个模拟器和设备中运行测试,而且我们可以在无线连接到服务器的设备上运行测试。 我们只需要将多个目标传递给xcodebuild。

实际例子

与上面的克隆相同,或下载Xcode9-XCTest项目并通过传递其他目标选项来运行xcodebuild命令。

  $ xcodebuild -scheme“ Xcode9-XCTest” -destination'platform = iOS Simulator,name = iPhone 7 Plus,OS = 11.0'-destination'platform = iOS Simulator,name = iPhone 7 Plus,OS = 10.3'构建测试CODE_SIGN_IDENTITY =“ “ CODE_SIGNING_REQUIRED =否 

内置Xcode服务器

Xcode Server是Apple提供的持续集成系统。 截至目前,Xcode Server需要macOS Server应用程序才能运行Xcode机器人。 现在,Xcode Server不再需要macOS Server应用程序。 它内置在Xcode中,可以从Xcode Preference中访问。 Xcode Server改进了功能,使用核心模拟器(无头)进行测试,并行测试多个设备,本地化控制。

实际例子

我分享了一篇详细的文章,内容涉及如何使用Xcode 9(即Xcode 9 + Xcode Server =全面的iOS持续集成)来设置Xcode Server。 随意导航到该文章,以从头开始学习有关Xcode Server设置的更多信息。

在此处观看GIF,了解如何为我们的演示项目Xcode9-XCTest创建Xcode机器人

结论

XCTest框架中的新功能,例如并行测试,自动配置,多应用程序测试,对于全球所有iOS团队无疑都是有用的。 苹果正在投入时间改善测试和持续集成实践。 希望近年来会继续下去。

像XCBlog的 XCTEQ 发布的帖子一样 您可能还喜欢我们的一些服务,例如访客博客或Mobile DevOps(CI / CD)或测试自动化。 Github 搜索我们的 服务 ,开源项目, 或者在 Twitter Facebook Youtube LinkedIn 上关注我们 下载我们的 XCBlog iOS应用程序以离线阅读博客。

X CTEQ 一家专门从事基于Mobile DevOps,CI / CD,Mobile,AI / ML的测试自动化Checkout XCTEQ产品和服务的公司, 网址 http://www.xcteq.co.uk 或写信给我们info@xcteq.co。英国..