移动自动化测试

通过查看上图可以最好地理解我们的系统。 蓝色突出显示的部分显示了测试的运行位置。 开发人员检入经过本地测试的代码更改,这些更改将由同级审查并提交给master分支。 该分支建立在Jenkins服务器上,并且在此阶段再次运行整套UI测试。 通过QA评估成功的构建,并在测试失败时报告新的错误。

为了防止一次实施UI测试并在启动失败后将其忘记,我们需要对自动化UI测试采用相同的CI / CD方法。 这意味着我们所有的测试代码都与我们的应用程序在同一个项目中,因此是持续集成管道的一部分。 当有新功能添加到应用程序时,新的UI测试可以同时添加到测试中。 当UI测试失败时,可以修复该错误并将其集成到主分支中,然后我们可以确保测试通过。 因此,上面显示的流程与用于正常代码更改(用于功能,错误修复等)以及添加和修复测试代码的流程相同。 将项目代码和测试代码都放在同一个CI系统中,可以提供高效的反馈系统,从而可以尽早发现错误并可靠地验证构建。

iOS测试框架

对于UI测试,我们使用Earlgrey 2.0。 Earlgrey是Google开发的一种测试框架,用于测试iOS的Google应用程序,并与XCTest(Apple的官方测试框架)集成在一起,该框架集成在XCode中。 在单独使用Earlgrey和XCTest进行了编写测试之后,我们决定使用Earlgrey。 做出此选择的主要原因是Earlgrey由于内置的​​功能而更加稳定,例如,在与元素进行交互之前等待视图完全加载,以及检查元素是否真正可见,而不仅仅是在UI堆栈中。

页面对象模型设计模式

对于我们的UI测试,我们决定遵循Page Object Model设计模式。

这种模式将用于识别UI元素的类与测试类分开。 每个“页面”或用户看到的屏幕都有自己的页面对象。 每个页面对象都有一些通用方法,例如verifyUIElements() ,只需调用这些方法即可验证屏幕上应该显示的所有元素是否可见。 它还具有代表用户操作的方法,例如tapDone()inputEmail() 。 然后,测试类可以调用这些方法以进行测试流程,例如导航到登录页面,验证元素,输入电子邮件地址,然后点击“登录”。这种方法减少了指定UI元素的代码重复。 此外,如果UI元素得到更新,则更新测试是对页面对象的单行更改,并且测试类不受影响。 这种分离也意味着测试类更具可读性。

请参阅以下示例在登录页面上进行UI测试。

上面是要测试的登录屏幕。 首先,我们制作了表示屏幕上UI元素的屏幕对象以及与这些元素进行交互的方法。

然后,我们编写了使用屏幕来测试登录流程的测试用例。 第一个测试用例是他们是否点击了“忘记密码”按钮,第二个是当他们输入有效的密码时。

测试套件

我们将测试套件分为健全性测试,冒烟测试和回归测试。 健全性测试将检查最少数量的功能,以确保构建实际上正在构建并正在运行。 如果这些测试失败,那么我们将陷入大麻烦。 冒烟测试检查了我们应用程序的更多基本功能,而回归测试则覆盖了我们应用程序的更多粒度和较少使用的功能。 进行健康与烟雾测试大约需要7分钟。 因此,我们希望开发人员在本地运行这两个套件,以确保在着陆更改之前,该构建适用于基本功能。 如果冒烟或健全性测试套件中的任何测试失败,则开发人员应在构建进行质量检查之前对它们进行检查,因为这可能表明存在重大问题。 由于回归测试套件大约需要30分钟,因此我们的Jenkins服务器每晚都会运行这些测试,并在第二天检查结果。 回归测试结果也很重要,但并不像健全测试和冒烟测试那样重要,因为每次测试都必须通过,因为对粒状细节的测试会变得更加脆弱。

模块化测试设计

我们努力设计测试,以使每个测试都尽可能模块化。 这意味着一个测试失败不会导致其他测试失败。 为了确保这一点,每个测试方案都以登录开始,并以注销结束。 一个测试场景可能是“以15%的小费收取Discover信用卡付款”,另一种情况是“以15%的小费收取MasterCard付款”。即使Discover测试失败,我们也会使用XCTest的teardown()函数返回屏幕上带有注销按钮,然后在开始下一个测试之前注销。 模块化在编写测试时为我们提供了帮助,因为您可以单独运行测试,并且调试速度更快。 查看测试结果时,这种模块化也有助于查明问题。 当测试失败时,测试框架将截屏显示失败的时间,失败之前的堆栈跟踪以及屏幕的整个UI层次结构。 对导致异常的测试框架的最后一次调用来自它正在尝试测试的屏幕对象,这使查看问题在哪个屏幕上的元素变得更容易。

到目前为止对团队和产品的影响

到目前为止,构建和运行测试使我们能够发现很多错误,尤其是对于不经常使用的iPhone模型。 通过在模拟器中运行测试,我们可以模拟不同的手机屏幕,这些屏幕可能导致UI元素移出视野并捕获那些显示错误。 作为编写测试的副作用,我们还能够发现现有代码中的不一致之处和错误,从而提高了应用程序体验的质量。

实施测试后,在构建版本进行质量检查之前,我们发现了许多错误。 通过我们的测试,可以在几个小时内发现并修复错误。 另一方面,如果我们没有在本地测试中发现错误,我们将推出一个构建(30分钟或更长时间),然后我们的质量检查人员将对该构建进行测试(从数小时到数天不等),希望可以找到并报告该错误,将其分配给开发人员,然后等待其修复。 这整个过程将花费数天而不是数小时,并且仅在发现错误的情况下。 如果它不是要由QA验证的修复程序之一,则他们可能完全错过了该错误。 通过我们的自动化测试节省的时间非常可观,并且可以总体上提高我们产品的质量。

但是,维护UI自动化需要付出努力。 到目前为止,我们了解到的一些事情是,测试不应过于精细,以至于它们很容易失败,并且记录常见的测试失败和常见的错误源有助于将来加快调试测试的速度(对于例如,“找不到应用程序包”仅表示需要重建应用程序代码)。 在完成初始设置并成为CI / CD管道的一部分之后,维护变得更加容易,并且值得团队长期节省下来的时间。