Xcode 13中非XCUITest测试修改设备方向的替代方案有哪些?
非XCUITest场景快照测试设备方向设置解决方案
原来使用XCUIDevice.shared.orientation = orientation.deviceOrientation设置方向的方式在Xcode13后被限制,仅XCUITest目标有权限调用,非XCUITest范畴的快照测试会抛出如下异常:
Failed to set device orientation: Not authorized for performing UI testing actions.
可以采用以下三种方案替代实现方向强制设置:
方案1:KVC修改UIDevice orientation属性(全系统版本兼容)
直接通过KVC修改UIDevice的私有属性触发方向变更,适配iOS13到最新系统,普通单元测试/快照测试均可正常调用:
// 先设置方向值:UIInterfaceOrientationLandscapeLeft对应值是4,LandscapeRight是3,Portrait是1,PortraitUpsideDown是2 UIDevice.current.setValue(NSNumber(integerLiteral: orientationRawValue), forKey: "orientation") // 触发系统方向变更更新 UIViewController.attemptRotationToDeviceOrientation() // 等待视图布局完成再执行截图操作 testView.layoutIfNeeded()
方案2:操作UIWindowScene设置方向(iOS13+官方推荐)
如果你的应用最低适配iOS13,可以直接通过window关联的scene修改方向,无需调用私有API:
if #available(iOS 13.0, *) { guard let windowScene = testView.window?.windowScene else { return } // 设置偏好方向 windowScene.requestGeometryUpdate(.iOS(interfaceOrientations: .landscapeLeft)) { error in print("方向设置失败: \(error)") } testView.layoutIfNeeded() } // iOS16及以上也可以用以下官方API if #available(iOS 16.0, *) { testViewController.setNeedsUpdateOfSupportedInterfaceOrientations() }
方案3:重写测试ViewController的支持方向属性
如果是针对单个ViewController做快照测试,可以直接在测试用例中重写该VC的supportedInterfaceOrientations属性,指定你需要的测试方向:
class TestTargetViewController: OriginalViewController { override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscapeRight } } // 初始化重写后的VC进行测试即可,系统会自动按照指定方向布局
注意事项
- 所有方向设置执行完成后,都需要主动调用对应视图的
layoutIfNeeded(),或者添加少量等待逻辑,确保视图完成旋转布局后再执行快照比对,避免拿到旋转前的错误截图 - 原有批量快照测试可以把方向设置逻辑封装到基类测试的
setup()方法中,无需逐个修改原有测试用例,最小化改造成本 - 不要在主应用生产代码中使用KVC修改私有属性的方案,该方案仅适用于测试场景
内容的提问来源于stack exchange,提问作者scaly
相关产品推荐
相关产品推荐

