XCUIApplication.launchArgumentsとArguments Passed On Launch

f:id:bamboohero:20210520092336p:plain UIテスト時はアニメーションをオフにしたり、アプリ初回起動時のダイアログを非表示にするなどの制御をしたいとき、UIテストコード側で以下のように起動時引数を与え、アプリコード側でその引数を参照して制御を行うことができます。

// UIテストコード
let app = XCUIApplication()
app.launchArguments.append("disableAnimations")

// アプリコード
if ProcessInfo.processInfo.arguments.contains("disableAnimations") {
    UIView.setAnimationsEnabled(false);  // アニメーションを無効化
}

また、XcodeのSchemeにも起動時引数の設定項目があります。

f:id:bamboohero:20210424005156p:plain:w700

この2つの関係性がいまいちわかっていなかったので調べてみました。

RunアクションのArguments Passed On Launchを指定する

Scheme設定画面の左側でRunを選択し、Arguments Passed On LaunchにrunActionという引数を追加します。

f:id:bamboohero:20210424010057p:plain:w700

そして、⌘+Rでアプリを起動します。

アプリコード内でProcessInfo.processInfo.argumentsを参照すると、runActionが含まれています。

// アプリコード
ProcessInfo.processInfo.arguments.contains("runAction")  // true

Runアクションなので、ここではUIテストコードは関係ないですね。

TestアクションのArguments Passed On Launchを指定する

Scheme設定画面の左側でTestを選択し、Arguments Passed On Launchでは「Use the Run action's arguments and environment variables」にチェックを入れておきます。

f:id:bamboohero:20210424010358p:plain:w700

そして、⌘+UでUIテストを実行します。

アプリコード内でProcessInfo.processInfo.argumentsを参照すると、runActionは含まれていません。

一方、UIテストコード内でProcessInfo.processInfo.argumentsを参照すると、runActionが含まれています。

// アプリコード
ProcessInfo.processInfo.arguments.contains("runAction")  // false

// UIテストコード
ProcessInfo.processInfo.arguments.contains("runAction")  // true

TestアクションでのArguments Passed On Launchの指定は、UIテストコード側に反映されるんですね。

今度は、「Use the Run action's arguments and environment variables」のチェックを外し、testActionという引数を追加してみます。

f:id:bamboohero:20210424010942p:plain:w700

そして、⌘+UでUIテストを実行します。

アプリコード内でProcessInfo.processInfo.argumentsを参照すると、testActionは含まれていません。

一方、UIテストコード内でProcessInfo.processInfo.argumentsを参照すると、testActionが含まれています。

なお、Runアクションで設定しているrunActionは含まれていません。

// アプリコード
ProcessInfo.processInfo.arguments.contains("testAction")  // false
ProcessInfo.processInfo.arguments.contains("runAction")  // false

// UIテストコード
ProcessInfo.processInfo.arguments.contains("testAction")  // true
ProcessInfo.processInfo.arguments.contains("runAction")  // false

XCUIApplication.launchArgumentsはどうなっているか?

TestアクションでArguments Passed On LaunchにtestActionを指定した状態で、UIテストコード側でXCUIApplication.launchArgumentsを参照するとどうなっているでしょうか?

見てみたところ、中身は空でした。

// UIテストコード
XCUIApplication().launchArguments  // []

まとめ

XCUIApplication.launchArgumentsとSchemeで設定するArguments Passed On Launchは直接の関係はないことがわかりました。

UIテスト時のこれらの設定については以下のようにまとめることができます。

  • UIテストコードに起動時引数を与える: Arguments Passed On Launch
  • アプリコードに起動時引数を与える: XCUIApplication.launchArguments

UIテストのコードが増えてくると、特定のSchemeのときだけ引数を与えて、UIテストコードの制御を行いたいことがあります。

そのようなときにはArguments Passed On Launchを使えば良いことがわかりました。