通过重新运行不稳定的XCUI测试来稳定iOS CI

Apple在WWDC 2015上发布了Xcode UI Testing aka XCUI Test framework,该框架无需使用Appium,Calabash或KIF等任何第三方工具即可直接从Xcode对iOS应用程序进行UI测试。 这些工具自称为移动测试框架,但实际上只不过是UIAutomation或Instruments的包装器而已。 随着Apple停止支持Instruments技术,iOS 10的发布打破了所有这些开源移动测试自动化框架。 剩下的唯一选择是使用Apple的XCTest框架,或者等待那些工具围绕XCUITest构建包装器。 XCTest不是一个新的框架,但是随着Xcode发行版的发展,它发展得相当不错。 您可以在此处阅读有关使用XCTest进行iOS应用测试的优缺点的更多信息

XCUITest +持续集成问题

XCUITest框架仍然是新的,有些用户已经抱怨它非常脆弱,尤其是当我们针对持续集成(CI)服务器运行时。 XCUI测试似乎在本地通过,但是这些测试对CI不确定。 您可以在StackOverflow上找到许多有关XCUITest的问题。 结果是,CI管道变得不可靠且不受信任。 团队一直忽略失败的UI测试,每个人对这些UI测试失去信任,这可能成为持续集成失败的原因。 损坏的UI测试始终被开发团队忽略。 但是,持续交付将不允许将损坏的版本部署到生产中。 现在,每个人都注意损坏的UI测试。 为了解决问题,团队可能会执行以下操作以确保您的UI测试尽可能具有弹性。

  • 遵循“端口和适配器”模式,以覆盖域层的所有业务逻辑,而无需编写任何UI测试。 很好的例子就是用Fitnesse编写更快的iOS验收测试或合同测试
  • 考虑使用存根后端或模拟Web服务器隔离测试UI,以防止意外数据替换真实Word UI测试。
  • 添加了XCUI计算的重试,以找到应用程序上的UI元素或循环运行,直到找到XCUIElement。
  • 在每个CI构建或每个测试套件上重置模拟器。
  • 向XCUITests添加了静态等待,以使测试可靠。

经过所有这些努力,也许很少有测试仍不确定,并且随机失败,人们会感到沮丧。 这是UI测试的常规行为,它们脆弱,易碎且难以维护,无论您付出了多少努力来进行修复,也无论您为防御它而付出了多少防御,运行时环境的特殊性都可能使您感到阴谋。

现在,由于不稳定的UI测试,您的正式发布已被阻止。 现在做什么 ?

在上述情况下,我们可以尝试一件明智的事情。 让我们以失败的XCUITests为例,尝试重新运行它们,但是挂起一个,还有另一个问题。 苹果的命令行工具“ xcodebuild”仍然没有从命令行运行单个XCTest的简便方法。 可能需要使用Xcode方案进行测试,但是将单个测试传递给“ xcodebuild”有点棘手。 新版本的“ xcodebuild”具有“仅测试”选项,但是使用脚本很难实现。 幸运的是,有一个名为“ fastlane-plugin-setup_fragile_tests_for_rescan”的fastlane插件可以解决不稳定的XCUI测试问题。 全部的感谢归功于插件“ lyndsey-ferguson”的作者。 这个插件做以下事情

  • 从快速通道扫描生成的Junit报告中进行失败的测试
  • 修改指定的XCUITest方案以跳过通过测试和失败测试的方案
  • 重新运行“扫描” 3次以查看测试结果。

修复当前的CI并继续进行很有意义,但是理想情况下,应该确定或删除不确定性测试,但是有时情况还不是那么完美,例如,您无法改善基础架构问题等。因此,这可能仍然是有效的措施。

让我们来看看

为了演示重新运行失败的XCUI测试,我创建了一个名为“ CoinTossing”的演示iOS应用。 该应用程序具有“投掷”按钮,并且textField显示了“投掷”或“尾巴”投掷的结果。 我们也有几个XCUI测试来检查结果。 测试失败的可能性为50%。

创建XCUITest方案并共享

让我们为XCUITest创建一个新方案,并将其命名为“ CoinTossingUITests”,并将其设置为“ Shared”,以便CI可以看到它,并传递给Fastlane扫描。

使用插件设置Fastlane

现在,我们将从Gemfile和bundler设置fastlane。 我们需要安装“ bundler” gem。

将fastlane添加到“ Gemfile”

 来源“ https://rubygems.org” 
 宝石“ fastlane” 

现在我们可以使用命令安装软件包

  $捆绑安装 

这将下载所有必需的fastlane工具。 我们将手动创建“ Fastlane”目录,并添加空的Fastfile。

  $ mkdire Fastlane 
  $ touch Fastlane / Fastfile 

现在我们需要使用命令将fastlane插件添加到项目中。

  $ bundle exec fastlane add_plugin setup_fragile_tests_for_rescan 

这将要求更改“ Gemfile”类型“ y”以允许的权限。 这将在“ Fastlane”目录下的“ Pluginfile”中创建另一个文件。

现在我们已经设置好插件,可以使用了。 让我们将以下代码添加到Fastfile中。

 泳道:test do | options | 
  scheme_to_test =“ CoinTossingUITests” 
  scan_options = { 
 方案:scheme_to_test, 
 设备:“ iPhone 6”, 
  output_directory:“工件/测试”, 
  custom_report_file_name:“ report.xml” 
  } 
 开始 
  retry_count || = 0 
 扫描(scan_options) 
 营救=> e 
  UI.important(“失败提示:#{e}”) 
  report_filepath = File.absolute_path('../ artifacts / tests / report.xml') 
除非File.exist?(report_filepath)
 提高e 
 结束 
 如果(retry_count + = 1)<3 
  setup_fragile_tests_for_rescan( 
  project_path:File.absolute_path('../ CoinTossing.xcodeproj'), 
方案:scheme_to_test,
  report_filepath:report_filepath 
  clear_derived_data 
 如果retry_count> 1,则reset_simulator_contents 
 重试 
结束
 结束 
 结束 

请注意,如果测试失败,我们会将’CoinTossingUITests’方案传递给快速通道扫描并运行扫描3次。 现在,我们应该能够运行“测试”通道

  $ bundle exec fastlane测试 

我们应该能够看到测试正在运行,并且如果测试失败,则只会再次运行失败的测试。 这将修改原始的“ CoinTossingUITests”方案。

使用Travis设置CI服务器

Fastlane插件“ fastlane-plugin-setup_fragile_tests_for_rescan”修改方案并仅添加失败的测试以重新运行。 它使用“ xcodeproj” gem修改方案设置,该设置与Cocoapods用于更改Xcode设置和文件的库相同。 此插件并非旨在在本地运行。 想法是在CI服务器上运行它们,我们不关心方案是否被修改,因为我们为每个构建签出新的源代码。 让我们将TravisCI配置添加到项目中,以便我们可以在CI服务器上运行它。 现在,启用存储库以在TravisCI上运行,并使用以下代码创建“ .travis.yml”文件

 操作系统: 
  -osx 
  osx_image:xcode8.2 
  xcode_sdk:iPhone 7(10.2) 
 语言:Objective-C 
before_install:
  -rvm安装2.3.3 
  -RVM使用2.3.3 
  -宝石安装捆绑器 
  -捆绑安装 
  #快取:cocoapods 
脚本:
  -密码 
  -xcrun simctl列表 
  -捆绑exec fastlane测试 

现在,我们应该能够在TravisCI上运行那些测试。 在此处签出TravisCI的最新输出

尝试一下

该演示的源代码可在GitHub存储库“ CoinTossing”上找到。 为了快速检查插件如何工作。 克隆项目并尝试运行测试。 假设您已经安装了Ruby环境,则可以运行以下命令来对此进行测试

  $ git clone https://github.com/Shashikant86/CoinTossing 
  $ cd CoinTossing 
  $ gem安装捆绑程序 
  $捆绑安装 
  $ bundle exec fastlane测试 

现在,您可以看到测试开始在模拟器中运行。 观察测试输出,如果一项测试失败,则应该看到该插件将重新运行,并进行多次测试,如上面的GIF所示。

要记住的事情

现在,我们应该重新运行失败的XCUI测试,以使CI满意并继续进行,但是在执行此操作之前,我们需要记住以下几点

  • 不要在本地使用Fastlane插件运行测试。 这个插件修改了方案,我们必须确保我们还原了插件所做的更改。 该插件只能在CI服务器上使用
  • 片状和不确定的测试应固定为合格或删除
  • 如果几次测试后测试失败,则将重试“扫描”计数保持为3,这表示测试确实存在问题。
  • 目前,如果重试计数大于1,我们将清除模拟器,但是,如果您真的想清除模拟器,则取决于您。

结论

Apple的新Xcode UI测试框架在CI服务器上可能有点不稳定,但是我们可以使用Fastlane插件重新运行不稳定的测试,以使XCUITests更加健壮和可靠。 希望这将有助于减轻CI服务器上不稳定的XCUI测试的麻烦。

像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。英国..