UI Testing in Xcode

这是2015年的WWDC session,因为对UI测试有一些困惑,所以特地看了一遍。
session地址
UI 测试最低支持iOS 9。
引用一段苹果开发指引里的话:

UI testing differs from unit testing in fundamental ways. Unit testing enables you to work within your app's scope and allows you to exercise functions and methods with full access to your app's variables and state. UI testing exercises your app's UI in the same way that users do without access to your app's internal methods, functions, and variables. This enables your tests to see the app the same way a user does, exposing UI problems that users encounter.

UI测试和单元测试是不同的,单元测试是在app内部运行,你有完整的权利去运行与访问方法和变量。而UI测试是让你用和用户一样的角度去使用和测试app,因此你没有权限去访问内部方法函数等。

核心技术

UI Testing in Xcode_第1张图片
Pasted Graphic.png

主要就是 XCTest 和 Accessibility,Accessibility主要为残障人士准备。


UI Testing in Xcode_第2张图片
Pasted Graphic 2.png

主要流程

  1. Adding a UI testing target
  2. Using recording
    1. Finding UI elements
    2. Synthesizing user events
  3. Adding validation with XCTAssert

这里引申到我在做 UI 测试的时候遇见的两个问题:如果我的App每次都要登陆,那么是不是我每个测试都得先做一遍登陆操作才能继续?如果我的某个功能点藏的层级很深,我是不是要一步步点进去?
先回答第二点:以我目前的了解来说,UI测试是以用户的视角操作app,因此我们不可能直接引入某个模块,直接传参进行调用,而是必须像用户一样一层一层点击,让app自行收集这些参数去调用。说白了在UI测试的时候,你要假设你对代码是 0 可知的。

APIs

Three new classes

  • XCUIApplication
  • XCUIElement
  • XCUIElementQuery
    UI测试引入了这三个新东西,以下将会做详细阐述。

XCUIApplication

Proxy for the tested application

  • Tests run in a separate process
    每次UI测试都是单独开线程,和工程代码隔离,生命周期也和工程代码独立,所以能在应用启动和终结的时候有更多的操作和控制(setup和teardown)

Launch

  • Always spawns a new process
  • Implicitly terminates any preexisting instance
    每次launch都是新的实例,是干净的状态,所以上面提到的问题如果不想每次测试都登陆一次,可以在setup里登陆好。而如果是一系列相关联的测试,可以一次性测试完。
    每次调用launch都会创建一个新的实例并终结之前的实例。

Starting point for finding elements

这也是查找元素的起点。

XCUIElement

Proxy for elements in application

Types

Button, Cell, Window, etc. 

Identifiers

Accessibility identifier, label, title, etc. 

注意到大多数元素都是通过Accessibility identifier去查找的

Most elements are found by combining type and identifier

通过类型和易用性id我们可以查找到绝大多数元素


UI Testing in Xcode_第3张图片
Pasted Graphic 5.png

Element Uniqueness

Every XCUIElement is backed by a query

每一个XCUIElement都是一个查询的返回,并且这个必须有且只有一个匹配项

Query must resolve to exactly one match

  • No matches or multiple matches cause test failure
  • Failure raised when element resolves query
    如果无法返回唯一查找结果,就会报出一个failure

Exception

``exists`` property 

XCUIElementQuery

API for specifying elements

更复杂的方式去查找指定元素

Queries resolve to collections of accessible elements

  • Number of matches:count
  • Specify by identifier: subscripting
  • Specify by index:elementAtIndex()

eg.

Type eg
Subscripting table.staticTexts[“Groceries”]
Index table.staticTexts.elementAtIndex(0)
Unique app.navigationBars.element

Accessibility and UI Testing

Debugging tips

Not accessible

  • Custom view subclasses
  • Layers, sprites, and other graphics objects
    这个在下文有示例解释

Poor accessibility data

Tools

  • UI recording Accessibility inspectors

上面这一段主要讲的是一些常见的无法进行 UI 测试的情况
常见的原因包括控件不可达:UI测试只能访达显示出来的 UI 组件、自定义控件未做 Accessibility 适配等。
Accessibility inspectors 就是检查
Accessibility 的工具。

ScreenShots

UI Testing in Xcode_第4张图片
Pasted Graphic 7.png

视频中提到了一个很有意思的功能,具体可参见30分钟处。
他在table中添加了一个Cookies,并且在之后添加了第二个Cookies。
随后的测试中因为UI 测试无法准确找到对应的组件而失败,这时报错信息是有两个Cookies。
然后,我们在 Report navigator 里可以看到错误发生的时候的ScreenShots,这是一个很有意思的功能。在跑测试的时候一般我们不会盯着app的运转,而当测试失败的时候,这些ScreenShots就可以帮我们回溯测试的过程,看看发生错误的时候app处于什么样的一个状态。

Record

还有一个功能是测试中的断点record,如果你在record的时候有一些冗余操作或者遗漏操作,你可能想整段删掉重新录入,但是你其实可以在恰当的位置打个断点,然后点击record,就可以继续录入。

小坑(待确认)

UI Testing in Xcode_第5张图片
Pasted Graphic 9.png

这个地方为什么用cells.count 而不是exist呢,是因为这里有个小坑,目前不知道这个坑是否依然存在


UI Testing in Xcode_第6张图片
Pasted Graphic 10.png

就是当cell元素被删除之后,它重新查找了元素,这里用的是index[0],删除之前是Apple,删除之后指向了Orange,所以exists判定仍然存在,只是不是Apple了

自定义元素

40分的时候还演示了一个不符合accessibility的元素是如何不能被查找到


UI Testing in Xcode_第7张图片
Pasted Graphic 13.png

这个红色待色块是一个custom view,并不是一个button所以查找不到,尽管我们的实现使得它的表现看起来像是一个button。因此点击 redView 的时候实际上record的是点击了cell[0],也就是cell在tableView中所在的位置。

那么怎么使得它能够符合accessibility的标准呢?


UI Testing in Xcode_第8张图片
Pasted Graphic 12.png

Enable并且指定它是button,就可以查找访问了

Attention

  1. 需要注意的是 UI 测试有一个不起眼的坑:
    如果在虚拟机上运行测试,有一个选项是把实体键盘链接到虚拟机中(见下图),因此虚拟机中的键盘是不会弹出的,如果我们在录制的时候使用了键盘操作,是不会被记录下来的,因此就会测试出错。比如测试的时候使用软键盘按了删除键,测试的时候链接了实体键盘就会测试失败,报找不到删除键。又如测试的时候链接了实体键盘,那么操作不会被记录,录制下来的操作就会和实际操作不符。


    UI Testing in Xcode_第9张图片
    image.png

总结

UI Testing 是 Unit Testing 的补充,
Unit Testing 用来测试 Models 和Controllers,而 UI Testing 则是我们针对 View 的有力工具,以 user 的视角

Accessible 和UI Testable 因此而捆绑在一起,UI Testable 的应用也就会对残障人士更友好

你可能感兴趣的:(UI Testing in Xcode)