You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 03:54:00