大多数浏览器和
Developer App 均支持流媒体播放。
-
探索数码旋钮、触控板和 iPad 指针自动化
了解如何在 Xcode 13 的 UI 测试中与设备交互。探索全新的自动化输入法,包括 iPadOS 指针、watchOS Digital Crown 表冠和增强的 macOS 触控板滚动 API。
资源
相关视频
WWDC21
-
下载
大家好 欢迎来到WWDC 我叫杰里米高德曼 是XCtest测试团队的工程师 本片中我们将 在Xcode 13下进行UI测试 一起探索一下与设备交互的新方式 其中 我们将聚焦于 三个不同平台上的 三种新交互 它们是:iPadOS的Pointer指针 watchOS的Digital Crown 以及macOS的trackpad 我们先从iPadOS的Pointer开始吧
在iPadOS的13.4版本下 Apple引入了鼠标和trackpad支持 通过例如Magic Keyboard之类的配件 为用户提供了 与iPad交互的全新方式 许多开发者充分利用这些 将特定的指针行为和交互 加入自己的iPad App 例如自定义悬停动画 在Xcode 13中 我们提供了强大的新型API 来实现UI测试中 对于iPadOS指针的控制 这种API使我们可以 对iPad App的多种类型的指针交互 创建强大的自动测试 运行iPadOS 15以及以上的设备 都可以使用它 让我们一起来了解 这种新API的更多细节 首先 我们对XCUIDevice 添加一项新的属性 该属性用于指示 此设备是否支持指针交互 然后我们在XCUIElement中 添加新方法 来执行不同的指针交互 例如悬停 多种类型的点击 以及双指滚动 我们同样还要添加一些 实现更复杂点击-拖拽的方法 以及结合一个或多个修饰键 一起使用需要的 执行程序块的经典方法 若需要更高精确度 这些方法都包含在XCUICoordinate中 我们一起来探索 这些新API在实践中如何工作 为一个iOS App的一种指针交互 创建一个新的UI测试 本次演示我使用的是Fruta App 在刚启动时 这个边栏是隐藏状态的 我为iPad新添加了一个指针功能 在trackpad上的双指横扫 可以打开边栏 现在我们为这个功能创建UI测试 这是一个空的UI测试的类 我将在这里添加新的UI测试
咱们快速串讲一下测试流程 首先要启动App 然后使用断言 使边栏在初始启动时处于隐藏状态 然后执行在trackpad上 的双指横扫动作 接着使用断言使边栏解除隐藏变为可见 还有另一点我想要强调一下 就是测试方法中 添加的这个“可用”属性 当你使用的方法 只对于某iOS版本及以上才可用时 这条属性就非常必要 本案例中 从iOS 15.0开始 才引入了这些指针交互API 现在我们去iPad模拟器上运行测试 诸位可以跟随光标的指引进行观看 光标就是画面左下角的 那个黑色圆形
太好了 看起来我们的测试 在iPad上运行顺利 这个App还有iPhone版的 但是iPhone上不支持指针交互 那么我们在iPhone模拟器上 运行一下本测试
看起来测试运行失败 错误信息如下 “本设备不支持指针事件” 要解决这个问题 我们就要修改测试代码 使之只能 在支持指针交互的设备上执行 我们可以通过使用XCTSkipUnless语句 通过XCUIDevice的 supportsPointerInteraction属性 使之在设备不支持时 直接跳过测试而非失败报错 现在我们再去 iPhone模拟器上运行测试 很好 在不支持指针交互的设备上 测试就被跳过了 咱们来聊聊 其他平台的设备的新交互方式 准确点说 watchOS上的Digital Crown 您或许已经知道了 Xcode 12.5为watchOS的App们 引入了UI测试支持 其中包括了watchOS新近可用的 将触摸事件以及 例如“按下Crown”的 硬件按钮事件进行整合的 各种方法 Xcode 13中 这支持进一步得到丰富 引入新的方法 将Digital Crown的旋转也整合进来 这个方法只要求一个参数 即旋转的圈数 还有一个可选的速度参数 用于说明旋转Crown的速度 这个速度参数 写为XCUIGestureVelocity 这意味着您可以在预设值中选一个 例如慢速,快速和默认 也可以明确将每秒钟转数 指定一个十进制值 我们一起看一下这个新方法的实践效果
假设我的watchOS上 安装了一个简单的天气App 用于显示当前的外部气温 这个App有一个功能 用户可以将Digital Crown往前拧 来查看未来的气温预报 或者往后拧 来查看过去的气温记录
我们来进行一个基础UI测试 以确定这项Crown旋转功能 可以如预期一样执行 测试第一步是启动这个App 然后用断言 使forecast time label 最开始显示当前温度 然后我们将Digital Crown 往前旋转1圈 随后使用断言 使之显示“一小时之后” 接着 我们将Crown往后旋转2圈 使用断言 使之显示“一小时之前” 测试到此结束 最后我们来聊聊macOS的trackpad 更准确说 我们聚焦于滚动功能 滚动动作可以划分为两大类 离散型和连续型 离散型滚动由精确的刻度式运动构成 回想一下 我们使用物理鼠标时的经历 在滚动轮每动一下 屏幕上的内容就会滚动过一段相同长度 而且这种滚动是没有惯性的 也就是说当您停止滚动滑轮 画面就会马上停止运动 另一方面 连续型或者称阶段型滚动 是一种流畅动态的运动 比如在trackpad上 双指滑动进行图片观看 屏幕上的内容 随着您的滑动流畅的鱼贯而过 这种运动是有惯性的 即当您的手指离开屏幕时 画面运动还会继续 并逐渐减速直到静止
XCTest目前可以提供 macOS下的滚动方法 使您可以在UI测试中 使用精确到像素的 离散型滚动 这个方法需要2个参数 用以指定滚动动作具体的 水平和垂直像素距离
Xcode 13中我们引入了一些新方法 用以整合macOS下连续型 或者类似trackpad一样的 滚动动作 这些方法接受一个可选的速度参数 用以明确你期望的滚动速度 这个速度参数写为 XCUIGestureVelocity 和我们早前进行的 旋转DigitalCrown方法一样 这个参数可以使用预设 也可以直接自定义一个每秒几像素的 具体十进制数值
Xcode 13为多个平台引入了API 从而实现新的输入方法的自动化 可以为更多具体的实用案例提供支持
这项新功能可以创建 iPad App中特定指针交互的UI测试 watchOS中Digital Crown 自动旋转的UI测试 以及macOS下 以新的扫屏方法进行的 连续的 类trackpad的滚动 若您有兴趣了解更多 请观看其各自的相关章节视频
感谢您的观看 希望您的WWDC过得愉快 [音乐]
-
-
1:28 - New supportsPointerInteraction property on XCUIDevice
extension XCUIDevice { public var supportsPointerInteraction: Bool }
-
1:37 - New methods on XCUIElement and XCUICoordinate for pointer interactions on iOS
extension XCUIElement { open func hover() open func click() open func rightClick() open func doubleClick() open func scroll(byDeltaX: CGFloat, deltaY: CGFloat) open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement) open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement, withVelocity: XCUIGestureVelocity, thenHoldForDuration: TimeInterval) open class func perform(withKeyModifiers flags: XCUIElement.KeyModifiers, block: () -> Void) }
-
2:31 - Empty UI test class
import XCTest class Pointer_UI_Tests: XCTestCase { }
-
2:43 - UI test for opening the sidebar with a two-finger horizontal trackpad swipe
import XCTest class Pointer_UI_Tests: XCTestCase { @available(iOS 15.0, *) func testHorizontalScrollRevealsSidebar() throws { let app = XCUIApplication() app.launch() let sidebar = app.tables["Sidebar"] // Make sure sidebar menu is not present initially. XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially") // Swipe horizontally to reveal sidebar. app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0) // Verify sidebar is now present. XCTAssertTrue(sidebar.waitForExistence(timeout: 5), "Sidebar did not appear within 5 second timeout") } }
-
import XCTest class Pointer_UI_Tests: XCTestCase { @available(iOS 15.0, *) func testHorizontalScrollRevealsSidebar() throws { try XCTSkipUnless(XCUIDevice.shared.supportsPointerInteraction, "Device does not support pointer interaction") let app = XCUIApplication() app.launch() let sidebar = app.tables["Sidebar"] // Make sure sidebar menu is not present initially. XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially") // Swipe horizontally to reveal sidebar. app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0) // Verify sidebar is now present. XCTAssertTrue(sidebar.waitForExistence(timeout: 5), "Sidebar did not appear within 5 second timeout") } }
-
5:27 - New method on XCUIDevice for Digital Crown rotation on watchOS
// New rotateDigitalCrown API extension XCUIDevice { open func rotateDigitalCrown(delta: CGFloat, velocity: XCUIGestureVelocity = .default) }
-
6:22 - UI test to verify the app's Digital Crown rotation functionality behaves as expected
// Example use of watchOS Digital Crown API func testForecastScrolling() { let app = XCUIApplication() app.launch() let forecastTime = app.staticTexts["forecast-time"] XCTAssertEqual(forecastTime.label, "Current Temperature") // Scroll 1 full rotation forward. XCUIDevice.shared.rotateDigitalCrown(delta: 1.0) XCTAssertEqual(forecastTime.label, "One hour from now") // Scroll 2 full rotations backward. XCUIDevice.shared.rotateDigitalCrown(delta: -2.0) XCTAssertEqual(forecastTime.label, "One hour ago") }
-
7:46 - Existing API for performing discrete (mouse wheel-like) scrolling on macOS
extension XCUIElement { // Use the existing API for discrete (mouse wheel-like) scrolling. open func scroll(byDeltaX: CGFloat, deltaY: CGFloat) }
-
8:05 - New API for performing continuous (trackpad-like) scrolling on macOS
extension XCUIElement { // Use the new API for continuous (trackpad-like) scrolling. open func swipeUp(velocity: XCUIGestureVelocity = .default) open func swipeDown(velocity: XCUIGestureVelocity = .default) open func swipeLeft(velocity: XCUIGestureVelocity = .default) open func swipeRight(velocity: XCUIGestureVelocity = .default) }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。