UI Testing 可以通过 XCUIApplication()
获取整个 app 的对象。通过其 staticTexts
、 buttons
等属性得到一个 XCUIElementQuery
对象,进一步获取 XCUIElement
对象来操作 UI 达到测试的目的。
WebView 中的 html 对象,也是可以通过以上方式获得的。UITesting 是基于 Accessibility。UI Accessibility 在 iOS 3.0 就被引入了,功能是对屏幕上的 UI 进行分类和标记,配合屏幕阅读技术 VoiceOver 和语音控制,用户在不触摸屏幕的情况下就可以通过声音来控制 app , 达到让身体不便的人士使用 app 的目的。
但是因为最初 Accessibility 和 VoiceOver 都是基于英文的,中国国情相对对残障人士的关爱也比较有限(例如无障碍通道的数量,盲道的设计和维护),
所以这些功能并不收到重视。不仅如此,完善这些功能对于开发者来说也是很大的工作量,所以基本不受到重视。
UI Testing 的本质就是定位屏幕上的元素,进行点击、拖动、输入等操作交互,然后获取状态判断是否符合预期。例如在 UI-Testing-Cheat-Sheet 中,就可以很方便的在 WebView 中使用 UI Testing:
func testTextExistsInAWebView() {
app.buttons["More Info"].tap()
let volleyballLabel = app.staticTexts["Volleyball"]
waitForElementToAppear(volleyballLabel)
XCTAssert(volleyballLabel.exists)
}
func testTappingALinkInAWebView() {
app.buttons["More Info"].tap()
let disambiguationLink = app.links["Volleyball (disambiguation)"]
waitForElementToAppear(disambiguationLink)
XCTAssert(disambiguationLink.exists)
disambiguationLink.tap()
let volleyballLink = app.links["Volleyball (ball)"]
waitForElementToAppear(volleyballLink)
XCTAssert(volleyballLink.exists)
}
但是很遗憾,通过 staticTexts[xxx]
、 links[xxx]
这样的方式在 WebView 中获取元素暂不支持中文,在中文网页中,我们无法通过这样的方式完成 UI Testing。
这里只能通过一种死板的方式进行 UI Testing: 获取到 webView 元素后,直接触摸一个指定的坐标,从而达到操作元素的目的:
func testLogin() {
let app = XCUIApplication()
let webView = app.webViews.element
// 这里简单的用 sleep() 来等待
// 根据网页加载速度适当调整,尤其是第一次需要等待较长时间
sleep(5)
// 触摸一个位置
let coordinate = webView.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
coordinate.tap()
// 这里等待是为了看到操作效果
sleep(5)
}
注意:
CGVector
中的dx
、dy
并不是像素,而是以webView
元素的origin
为原点,以webView
的frame
为大小,做出偏移的百分比。例子中的
CGVector(dx: 0.5, dy: 0.5)
即是webView
的中心点,左上角为CGVector(dx: 0, dy: 0)
,右下角为CGVector(dx: 1, dy: 1)
。可能在不同大小的屏幕中元素的位置还有差别,要引起注意。
如果要想测试输入功能,只要在弹起键盘之后,调用 XCUIApplication().typeText("admin123")
的方式即可完成。只需要注意网页的响应时间,在适当的操作中加入适当的等待时间,在 WebView 中使用 UI Testing 也就不成问题了。