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

运行macOS应用XCTest时意外触发系统深色模式问题求助

macOS XCTest 运行时意外切换系统主题至深色模式的解决方案

问题描述

我为macOS应用编写了多组XCTest测试用例,运行最后一个测试时会意外将整个系统主题切换为深色模式,每次都需手动前往系统设置改回,但我并未编写任何切换主题的逻辑。
环境:macOS Sequoia 15.2、Xcode 16.2

测试代码如下:

单元测试代码

import XCTest
@testable import TipCalculatorMac

final class TipCalculatorAppTests: XCTestCase {
    func testRemoveRow() {
        let viewModel = BillViewModel()
        viewModel.rows = [
            BillRow(billAmount: 100, tipPercentage: 10),
            BillRow(billAmount: 200, tipPercentage: 20),
        ]
        let initialCount = viewModel.rows.count
        viewModel.rows.remove(at: 0)
        XCTAssertEqual(viewModel.rows.count, initialCount - 1, "Removing a row should decrease the count of rows by 1")
    }
}

UI测试代码

import XCTest

final class TipCalculatorMacUITestsLaunchTests: XCTestCase {
    override class var runsForEachTargetApplicationUIConfiguration: Bool {
        true
    }

    override func setUpWithError() throws {
        continueAfterFailure = false
    }

    @MainActor
    func testLaunch() throws {
        let app = XCUIApplication()
        app.launch()

        let attachment = XCTAttachment(screenshot: app.screenshot())
        attachment.name = "Launch Screen"
        attachment.lifetime = .keepAlways
        add(attachment)
    }
}

问题原因

核心原因在于UI测试类中的runsForEachTargetApplicationUIConfiguration = true配置:这个属性会让测试针对应用支持的所有UI配置(包括浅色、深色模式)分别执行一次。测试过程中系统会临时切换全局主题来适配测试场景,但在测试结束后可能没有正确恢复到原有主题。

解决方法

1. 关闭多UI配置自动测试

如果不需要针对不同主题分别测试,直接将该属性改为false即可阻止系统自动切换主题:

override class var runsForEachTargetApplicationUIConfiguration: Bool {
    false
}

2. 强制测试使用指定主题

若需要保留多配置测试,但不想影响系统全局主题,可以在启动应用时通过参数强制指定应用的外观模式,避免系统全局切换:

override func setUpWithError() throws {
    continueAfterFailure = false
    let app = XCUIApplication()
    // 强制设置为浅色模式,如需深色则改为"Dark"
    app.launchArguments += ["-AppleInterfaceStyle", "Light"]
    app.launch()
}

3. 测试结束后手动恢复系统主题

如果必须依赖系统主题切换完成测试,可以在测试结束后通过AppleScript调用系统设置恢复原有主题:

override func tearDownWithError() throws {
    // 恢复为浅色模式,需要深色则改为true
    let script = """
    tell application "System Events"
        tell appearance preferences
            set dark mode to false
        end tell
    end tell
    """
    let task = Process()
    task.launchPath = "/usr/bin/osascript"
    task.arguments = ["-e", script]
    task.launch()
    task.waitUntilExit()
    
    try super.tearDownWithError()
}

注意:使用此方法需要给Xcode开启「辅助功能」权限,路径为:系统设置 → 隐私与安全性 → 辅助功能,勾选Xcode。

内容的提问来源于stack exchange,提问作者user185929

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:43:11