web-dev-qa-db-ja.com

iOSアプリがUIテストモードで実行されているかどうかを検出する方法

UIテストモードで実行しているときに、アプリで特別なコード(たとえば、状態のリセット)を実行したいです。アプリをUI Testingから実行しているときに設定される環境変数を調べましたが、アプリの通常の実行とUI Testingを区別する明確なパラメーターはありません。調べる方法はありますか?

私が満足していない2つの回避策は次のとおりです。

  1. XCUIApplication.launchEnvironmentに、後でアプリでチェックする変数を設定します。各テストファイルのsetUpメソッドで設定する必要があるため、これは良くありません。スキーム設定から環境変数を設定しようとしましたが、UIテストテストの実行時にアプリ自体に伝搬されません。
  2. 環境変数__XPC_DYLD_LIBRARY_PATHが存在しないことを確認してください。これは非常にハックが多いように見え、ターゲットビルド設定のセットアップ方法が偶然一致したために、現在のみ機能している可能性があります。
38
Liron Yahdav

私は自分でこれを研究してきましたが、この疑問に出会いました。 @LironYahdavの最初の回避策に行き着きました。

UIテストで:

- (void)setUp
{
    [super setUp];

    XCUIApplication *app = [[XCUIApplication alloc] init];
    app.launchEnvironment = @{@"isUITest": @YES};
    [app launch];
}

アプリで:

NSDictionary *environment = [[NSProcessInfo processInfo] environment];
if (environment[@"isUITest"]) {
    // Running in a UI test
}

@JoeMasilottiのソリューションは、テスト対象のアプリと同じランタイムを共有しますが、UIテストには関係ないため、nitテストに役立ちます。

51
jnic

起動環境の設定に成功しませんでしたが、起動引数を使用して動作させることができました。

テストでsetUp()関数を追加します:

  let app = XCUIApplication()
  app.launchArguments = ["testMode"]
  app.launch()

本番コードに次のようなチェックを追加します。

let testMode =  NSProcessInfo.processInfo().arguments.contains("testMode")
if testMode {
  // Do stuff
}

XCode 7.1.1を使用して検証済み。

10
Ciryon

これには、プリプロセッサマクロを使用できます。選択肢がいくつかあることがわかりました。

新しいターゲット

アプリのターゲットのコピーを作成し、これをテスト対象として使用します。このターゲットコピー内のすべての前処理マクロには、コードでアクセスできます。

欠点の1つは、コピークラスにも新しいクラス/リソースを追加する必要があり、時には忘れがちなことです。

新しいビルド構成

Debugビルド構成の複製を作成し、任意のプリプロセッサマクロをこの構成に設定し、テストに使用します(下のスクリーンショットを参照)。

ちょっとした落とし穴:UI TestingセッションをrecordしたいときはいつでもRunを変更して新しいテスト設定を使用する必要があります。

重複した構成を追加します。

Add a duplicate conf

あなたのテストに使用してください:

Use it for your *Test*

5

この拡張機能を追加しました

 @available(iOS 9, *)
 extension XCUIApplication {

 func test(){
   launchEnvironment = ["TEST":"true"]
   launch()
  }
 }

したがって、launch()の代わりにtest()を使用できます。

3
andrea sciutto

以前の回答に基づいたSwift 3。

class YourApplicationUITests: XCTestCase {

    override func setUp() {
        super.setUp()

        // Put setup code here. This method is called before the invocation of each test method in the class.

        // In UI tests it is usually best to stop immediately when a failure occurs.
        continueAfterFailure = false
        // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
        let app = XCUIApplication()
        app.launchArguments = ["testMode"]
        app.launch()

        // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // Use recording to get started writing UI tests.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

}


extension UIApplication {
    public static var isRunningTest: Bool {
        return ProcessInfo().arguments.contains("testMode")
    }
}

次に、コードでUIApplication.isRunningTestを呼び出すだけです。

1
GregP

私のソリューションは、 Ciryonのもの とほぼ同じです。ただし、私のmacOSドキュメントベースのアプリの場合を追加する必要がありました引数名にハイフン

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

...そうでない場合、「テスト」はアプリの起動時に開くドキュメントのとして解釈されるため、エラーアラートが表示されていました。

enter image description here

0
Nicolas Miari

Swift 3では、XCInjectBundleIntoキー、またはXCで始まるものを確認できます。

let isInTestMode = ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil

これはOS Xでも機能します。

0
Oleander