iOS管道中DevOps友好XCTest的重要提示

最初在 这里 发布在XCBlog上

苹果已经引入了XCTest框架,可以为各种苹果平台创建单元,集成,性能和UI测试。 XCUITest是XCTest之上的一个性感扩展,它使开发人员可以为iOS和macOS应用编写UI测试。 自从在WWDC 2015中启动以来,XCUITest受到了很多关注和增强。 它使用Swift语言创建测试,这使iOS开发人员可以轻松地使用相同的编程语言为iOS应用程序添加UI测试。 另一方面,DevOps和Continuous Delivery实践诱使企业在开发新功能后立即发布它们。 根据权衡,单元和集成测试是轻量级的,并且速度更快。 但是,UI测试非常缓慢,难以维护。 许多移动测试金字塔表明,我们应该进行最少的UI测试,并涵盖业务逻辑较低级别的轻量级测试。 但是,UI测试是不可替代的,并且如果执行得当,则可以在更高的级别上提供更多的价值。 就发布应用程序的信心而言,单个UI测试可以击败数千个单元测试。 为了混合使用DevOps和XCTests的实践,我们必须在不干扰CI / CD管道的情况下,就如何编写XCTest做出一些明智的决定。 在本文中,我们将介绍一些对DevOps友好的XCTests的技术。

为了允许频繁发布iOS应用,设置和维护CI / CD管道非常重要。 iOS开发中最痛苦的事情之一就是发布了该应用程序。 它涉及许多活动,这些活动可能容易出错,重复且耗时。 CI / CD管道的作用是使所有无聊的任务自动化。 典型的iOS发布管道包括以下内容

  • 查看源代码
  • Swift代码的静态分析(例如SwiftLint)
  • 编译和构建iOS应用
  • 运行各种测试,例如单元,集成,API,UI,性能,安全性
  • 代码签名和存档iOS应用
  • 将iOS应用分发到iTunes Connect或第三方测试服务
  • 创建标签或在Source Control上发布,例如Github Releases
  • 最后但并非最不重要的一点是,通过发行说明通知人们有关新版本的信息

可能有更多的东西正在筹备中,但上面列出了一些非常常见的东西。 很明显,如果没有自动化测试,CI / CD管道将无法完成。

自动化测试提供了释放iOS应用程序的价值和信心,而无需担心。 现在,我们将看到如何精巧地编写XCTest,以在不影响iOS应用程序质量的情况下加速管道。

用单元测试覆盖所有生产代码始终是一个好主意,这样Continuous Integration可以在生命周期的早期检测到错误。 单元测试通常写得很快,而且琐碎。 使用XCTest,我们可以通过编写单元测试来覆盖大多数代码。 在某些情况下,我们必须编写集成测试,而单元测试不足以覆盖业务逻辑。 进行轻量级和更快的测试的好处是生成速度更快,可以提供早期反馈。 苹果在这里用XCTest框架编写单元测试的文档非常丰富

iOS应用程序使用后端或服务器端API是一种非常常见的做法。 确保iOS应用使用的API遵循消费者驱动的合同,这一点非常重要。 否则,他们可能会完全破坏iOS应用程序。 为iOS团队提供API的团队之间必须有合同和沟通,以避免破坏iOS应用。 这引发了合同测试的需要,从而确保了API提供程序和客户端之间的通信而无需进行脆弱的集成测试。 使用XCTest框架,我们可以绘制合同并自动执行网络测试。 我们还可以在Swift中使用Pact测试工具来执行合同测试。 Github上有一个库,可以在这里使用Swift使用Pact进行合约测试

iOS应用的速度是在当前竞争激烈的市场中取得成功的关键。 XCTest框架具有度量模块,可以将其应用于测试方法内的任何代码以检查代码的性能。 但是,后端API应该由负责构建这些API的团队分别进行性能/负载测试。 您可以阅读本文以获取有关XCTest性能测试的详细指南。 为iOS发布管道添加性能测试可以使其更加稳定,我们可以在将应用程序上载到iTunes Connect之前更早地检测到性能问题。 但是,性能测试非常缓慢,只能在需要时运行,例如在发布之前或作为夜间构建的一部分。

苹果在Accessibility上投入了大量资金,并且已经在UIKit框架中诞生。 可访问性使iOS应用程序可用于所有人(包括残疾人),还有助于使用XCTest进行UI测试。 您可以在此处阅读添加UI测试的可访问性添加UI元素的可访问性可以使UI测试更快,从而减少了整个构建时间。

XCTest框架可以扩展为用户界面测试,也称为XCUITests。 我们可以根据需要添加任意数量的UI测试,但是请记住,UI测试缓慢,脆弱且耗时。 我们应该尝试在集成和API级别上测试大多数业务逻辑,并为UI测试保持关键的用户旅程。 可以在任何macOS服务器计算机上以无头模式运行XCUITests,但它们仍然很慢并且需要保持最小。

当XCTest框架用于测试iOS应用程序时,它会启动模拟器来执行测试。 但是,从Xcode 9开始,从命令行运行时,XCTest和XCUITests可以无头模式运行。 任何macOS服务器都可以运行XCTest,但它还不足以在模拟器中运行测试,我们也需要它们在真实设备上运行。 在发布iOS应用之前,我们应该从真实设备中获取反馈。 在Continuous Integration服务器上,如果您具有自托管的CI,则可以连接某些设备,或者可以使用诸如SauceLabs,Perfecto或AWS Device Farm之类的云测试服务。

Apple的XCTest工具或其他开发人员工具足以执行大多数质量保证检查。 还有其他一些第三方Swift库,例如Quick,可用于进行规格级别的单元测试,从而在iOS应用中添加了不必要的依赖项。 还有第三方UI测试工具(如Appiumor Calabash),该工具允许使用其他语言(如Java,Ruby等)编写测试。这些工具在开发人员和QA工程师之间建立协作时更加危险,并且很难插入CI / CD管道中要求安装不必要的技术,并在CI服务器上完成其他脆弱的配置。 使用XCTest之类的本机工具可使CI / CD管道更易于配置维护。 如果您的项目是本机(Swift),请保持其本机,除非需要,否则不要引入任何依赖项。 使用不相关的技术会增加项目的构建时间和复杂性,例如在iOS项目中引入Java或Ruby效果不佳。

iOS应用程序默认具有Debug和Release构建配置。 创建另一个用于测试目的的构建配置总是一个好主意,我们可以将其称为Test或类似的名称。 有了这种灵活性,我们就可以为内部用户设置释放调试配置。 我们仍然可以为测试配置添加一些与测试相关的配置。 这也降低了将测试代码泄漏到生产应用程序的风险。 使用不同的构建配置使我们可以添加特定于测试的代码,从而使测试的执行速度更快,并涵盖了测试的大部分业务逻辑。

编译和构建iOS应用程序需要花费大量时间。 一些团队使用不同的方案来构建用于单元和UI测试的应用程序。 这在持续集成过程中增加了不必要的构建时间。 最好使用xcodebuild功能(如此处提到的用于测试的构建和无需构建的测试)。我们还可以将xctestrun文件用于分布式CI构建机器,以节省构建时间。

在iOS开发中,使用正确的Continuous Integration服务器运行我们为iOS应用编写的所有XCTest非常重要。 它可以是自托管的或基于云的CI系统。 此处提到的一些原因是,如果使用或选择不正确,CI可能会完全失败。

幸运的是,XCTest框架是一个多用途工具,可以用于单元,测试,集成测试,API测试和性能测试。 这减轻了添加第三方工具来覆盖不同类型测试的负担。 简而言之,XCTest在这里将它们全部统治,并使iOS测试对DevOps越来越友好。 您使用什么技术来使XCTest DevOps或CI友好? 请放弃以下评论