为iPhone和iPad构造iOS XCUITests

Apple的XCUITest框架是iOS应用程序UI自动化的热门且新兴框架,自从WWDC 2015推出以来,受到了广泛关注。

XCUITest允许我们在Swift中为iOS应用编写UI测试,这使iOS开发人员可以轻松为iPhone和iPad的iOS应用添加UI测试。 必须同时考虑XCUITests的iPhone和iPad,因为使用iPad上的应用程序的用户不能被忽略。 使用XCUITest,由于使用相同的框架(即XCTest)编写了单元和UI测试,因此持续集成和持续交付变得轻而易举。 在XCUITest之前,Appium,Calabash等工具允许使用其他语言(如Ruby或Java)编写UI测试,这成为CI / CD和iOS开发流程的难题。 XCUITest可以为iOS应用编写,但是iOS设备具有不同的变体,例如具有不同屏幕尺寸的iPad和具有不同屏幕尺寸的iPhone。 我们必须确保XCUITests可以在所有变体上完美运行,而不会引起很多重复。 如果XCUITest的架构正确,那么我们可以避免重复代码,并且仍然能够在不同版本上运行所有XCUITest。 在本文中,我们将介绍如何为iPhone和iPad构建XCUITest。

XCUI测试

XCUITest新手肯定应该观看WWDC视频,以了解XCUITest框架的基本功能。 XCUITest允许我们使用Apple自己的编程语言Swift为iOS应用编写测试。 它与其他第三方框架(如Appium,Calabash等)有很大不同。如果您想将XCUITest与Appium进行比较,请阅读这篇文章,以更好地了解每个框架。 如果您想了解所有新XCUITest功能的动手探索,请参考我以前的博客文章“使用Xcode 9的新XCUITest功能”,其中我已详细介绍了几乎所有功能。 您可以按照DZone上这篇博文中提到的为XCUITests设置面向协议的体系结构,第二部分可以在这里获得。 我们可以使用WWDC 2017演讲中有关可测试性工程的演讲中提到的一些技术来使XCUITest可扩展bu,重点是可测试代码。

UIDevice和XCUIDevice

苹果提供了UIDevice类来获取当前设备的表示,并提供了XCUIDevice类来模拟物理按钮和设备方向。 如果我们正确地组织了XCUIElement,那么在iPhone和iPad上进行架构测试就变得如此容易。 使用UIDevice API,我们可以使用以下代码获取当前运行测试的设备

 如果UIDevice.current.userInterfaceIdiom == .pad { 
  //做iPad的东西 
  } 

使用XCUIDevice,我们可以使用以下代码将设备方向设置为横向或纵向

  XCUIDevice.shared()。orientation = .landscapeRight 

这两个API对在iPhone和iPad上设置XCUITests极为有用。

避免两个套房

在许多项目中,我看到人们为iPhone和iPad创建了两个单独的测试套件。 在iPad和iPhone中,有两种单独的Xcode方案可以执行测试。 在整个测试中也有条件执行,这对于管理测试套件很困难。 我们不需要像使用本文中提到的方法那样进行操作。 稍后,我们将尝试找到解决这些问题的方法。

组织XCUIElement

在iPad和iPhone上构建XCUITests时,以适当的格式组织XCUIElement非常重要。 我强烈建议使用Swift枚举来组织屏幕上的元素。 请将此帖子参考XCUITest的面向协议的体系结构。 在我最近的有关使用Swift枚举组织XCUIElement的文章中,我解释了如何按照屏幕组织元素。 假设我们的iOS应用程序有一个主屏幕,其中包含三个按钮和两个静态文本。 我们可以这样写枚举

 导入XCTest 
枚举HomeScreen:字符串{
case guestButton =“你好”
case registerButton =“注册”
case loginButton =“登录”
case welcomeText =“欢迎”
case introText =“应用程序简介”
var元素:XCUIElement {
切换自我{
case .guestButton,.registerButton,.loginButton:
返回XCUIApplication()。navigationsBars [“ XYZ”]。buttons [self.rawValue]
大小写.welcomeText,.introText:
返回XCUIApplication()。staticTexts [self.rawValue]
}
}
}

我们已将字符串值分配给枚举案例,并将案例分组为按钮和静态文本。

iPad上的条件XCUIElements

由于所有按钮都是导航栏的一部分,因此上面提到的枚举将非常适合iPhone。 但是,如果遇到iPad设计所有按钮都在选项卡栏中的情况。 枚举中提到的方法不适用于iPad。 但是,如果设备是iPad,则使用UIDevice,我们可以有条件地从上述枚举中返回XCUIElement,如下所示

 导入XCTest 
枚举HomeScreen:字符串{
case guestButton =“你好”
case registerButton =“注册”
case loginButton =“登录”
case welcomeText =“欢迎”
case introText =“应用程序简介”
var元素:XCUIElement {
切换自我{
case .guestButton,.registerButton,.loginButton:
如果UIDevice.current.userInterfaceIdiom == .pad {
返回XCUIApplication()。tabBars [“ XYZ”]。buttons [self.rawValue]
}其他{
返回XCUIApplication()。navigationsBars [“ XYZ”]。buttons [self.rawValue]
}
大小写.welcomeText,.introText:
返回XCUIApplication()。staticTexts [self.rawValue]
}
}
}

现在,枚举将从iPad的选项卡栏和iPhone的导航栏返回按钮。 我们不必从访问这些XCUIElement的地方触摸一下实际的测试实现。 使用这种方法,我们可以避免代码的大量重复,并使我们的测试套件可用于所有设备的型号和方向。

结论

通过使用来自苹果的XCUITest,Swift枚举和UIDevice API的面向协议的体系结构,我们可以在iPhone和iPad设备上实现UI自动化,而无需重复代码。 在iPad场景的测试代码中,无需在每个地方创建单独的方案或添加条件。 希望您喜欢这种为iPhone和iPad设计架构测试的方法。 您对这种方法的看法,如果您想到一种更好的方法,请告诉我,始终乐于学习。

原始博客文章 在这里