如何访问 XCUIApplication 中设置的 launchEnvironment 和 launchArguments,在 XCode 中运行 UI 测试?

问题描述 投票:0回答:9

我已经尝试在

XCUIApplication
实例中设置属性,在我的 UI 测试中
setUp()

let app = XCUIApplication()
app.launchEnvironment = ["testenv" : "testenvValue"]
app.launchArguments = ["anArgument"]
app.launch()

didFinishLaunch
我试图在运行我的UITests时在屏幕上显示这些

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if launchOptions != nil {
        for (key, value) in launchOptions! {  
            let alertView = UIAlertView(title: key.description, message: value.description, delegate: nil, cancelButtonTitle: "ok")
            alertView.show()
        }
    }

但是我好像找不到我设置的参数和环境。任何人都知道如何抓住他们?

ios xcode swift ui-testing
9个回答
72
投票

如果您在 UI 测试(Swift)中设置

launchArguments

let app = XCUIApplication()
app.launchArguments.append("SNAPSHOT")
app.launch()

然后使用以下方法在您的应用程序中阅读它们:

swift 2.x:

if NSProcessInfo.processInfo().arguments.contains("SNAPSHOT") {
   // Do snapshot setup
}

斯威夫特 3.0

if ProcessInfo.processInfo.arguments.contains("SNAPSHOT") {
}

要设置环境变量,请分别使用

launchEnvironment
NSProcessInfo.processInfo().environment


18
投票

同样有趣的是,传递给

XCUIApplication.launchArguments
的参数也可以从
UserDefaults
获得。

在你的 XCTestCase 中

let app = XCUIApplication()
app.launchArguments.append("-ToggleFeatureOne")
app.launchArguments.append("true")
app.launch()

在你的被测目标中

UserDefaults.standard.bool(forKey: "ToggleFeatureOne") // returns true

从这里您可以在

UserDefaults
上创建扩展以提供方便的运行时切换。

这与 Xcode 方案“启动时传递的参数”使用的机制相同。启动参数及其对

UserDefaults
的影响记录在Preferences and Settings Programming Guide下。


17
投票

基于 Joey C. 的回答,我写了一个小扩展来避免在应用程序中使用原始字符串。这样你就可以避免任何错字问题并获得自动完成功能。

extension NSProcessInfo {
    /**
     Used to recognized that UITestings are running and modify the app behavior accordingly

     Set with: XCUIApplication().launchArguments = [ "isUITesting" ]
     */
    var isUITesting: Bool {
        return arguments.contains("isUITesting")
    }

    /**
     Used to recognized that UITestings are taking snapshots and modify the app behavior accordingly

     Set with: XCUIApplication().launchArguments = [ "isTakingSnapshots" ]
     */
    var isTakingSnapshots: Bool {
        return arguments.contains("isTakingSnapshots")
    }
}

这样你就可以使用

if NSProcessInfo.processInfo().isUITesting {
   // UITesting specific behavior,
   // like setting up CoreData with in memory store
}

更进一步,各种参数可能应该进入一个枚举,可以在设置 launchArguments 时在 UITest 中重用。


11
投票

这里是 launchArguments 和 Objective-C 的例子:

if ([[NSProcessInfo processInfo].arguments containsObject:@"SNAPSHOT"]) {
        //do snapshot;
}

斯威夫特:

    let arguments = ProcessInfo.processInfo.arguments
    if arguments.contains("SNAPSHOT") {
        //do snapshot
    }

7
投票

对于启动参数,将它们作为两个单独的参数传递:

let app = XCUIApplication()  
app.launchArguments.append("-arg")  
app.launchArguments.append("val")  
app.launch()

取自here.


7
投票

记住一些细节。首先,XCUIAppliction 不是单例,因此,如果您调用

XCUIApplication().arguments.append("myargument")
然后调用
XCUIApplication().launch()
,它不会发送参数。 在这里查看.

其次,如果您在启动应用程序后修改参数,它将不起作用,它会将新参数发送到下一次执行。


4
投票

我只知道这在 Objective-C 中是如何工作的

NSDictionary *environment = [[NSProcessInfo processInfo] environment];

1
投票

如果您需要将 environment variables 从您的模式传递给 XCUITes,请在每个测试类上修改 XCTestCase -> app.launchEnvironment 对象:

斯威夫特 3

override func setUp(){
    app.launchEnvironment = ProcessInfo.processInfo.environment
}

0
投票

1- 创建 ProcessInfo 的扩展

extension ProcessInfo {

    public enum LaunchArgument: String {
        case uiTestSampleData
        case uiTestStagingData
        case none
    }

    public var launchArgument: LaunchArgument {
    
        if arguments.contains(LaunchArgument.uiTestSampleData.rawValue) {
            return .uiTestSampleData
        }
    
        if arguments.contains(LaunchArgument.uiTestStagingData.rawValue) {
            return .uiTestStagingData
        }
    
        return .none
    }

}

2- 修改你的数据源初始化。在本例中我使用的是 Moya,所以我修改了 provider init。 不是正常启动您的 rest api,而是在 init 中检查参数并模拟 sameplData 参数的响应。

public init(provider: MyProvider<MyStoreApi> = MyProvider<MyStoreApi>()) {
    
    switch ProcessInfo.processInfo.launchArgument {
        
    case .uiTestSampleData:
        let provider = MyProvider<MyStoreApi>(stubClosure: MoyaProvider.immediatelyStub)
        self.provider = provider
        
    case .none, .uiTestStagingData:
        self.provider = provider
    }

}

3- 在 UI 测试中添加参数

app.launchArguments.append("uiTestSampleData")
© www.soinside.com 2019 - 2024. All rights reserved.