web-dev-qa-db-ja.com

XcodeでUIテストケースを高速化する方法

Xcode 7以降、UIテスト用の素晴らしいAPIがあります。主に私はそれに満足しています。唯一の懸念は速度に関連しています。

最初に、通常のUIテストケース(約15のアクション)が約25秒実行されました。次に、ネットワーキングを完全に模倣しました。今では20秒かかります。時間はアニメーションと起動時間(1秒以下)だけで済むことを考えると、スピードを上げる方法が必要だと思います。

18

UIテストの実行時にこのプロパティを設定してみてください。

UIApplication.shared.keyWindow?.layer.speed = 100

設定方法は次のとおりです。

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if ProcessInfo.processInfo.arguments.contains("UITests") {
        UIApplication.shared.keyWindow?.layer.speed = 100
    }
}

そして私のUIテストでは:

class MyAppUITests: XCTestCase {

    // MARK: - SetUp / TearDown

    override func setUp() {
        super.setUp()

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

これには、さらに便利なヒントがいくつかあります ブログ投稿

28
Mark

別の可能性は、アニメーションをまったく無効にすることです:

[UIView setAnimationsEnabled:NO];

スウィフト3:

UIView.setAnimationsEnabled(false)
9

@Markの回答に続いて、Swiftバージョン:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    if ProcessInfo.processInfo.arguments.contains("UITests") {
        UIApplication.shared.keyWindow?.layer.speed = 200
    }
}

あなたのUIテストファイル:

override func setUp() {
    super.setUp()

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

    let app = XCUIApplication()
    app.launchArguments = ["UITests"]
    app.launch()
5
mourodrigo

スナップショットテスト中は、すべてのアニメーションを無効にしたいと思っていました。以下のように、Core AnimationとUIViewアニメーションの両方を無効にすることで、これを実現できました。

私のアプリはストーリーボードを使用したので注意してくださいUIApplication.shared.keyWindowは起動時にnilだったので、windowプロパティを直接参照してUIWindowにアクセスしました。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if ProcessInfo.processInfo.arguments.contains("SnapshotTests") {
        // Disable Core Animations
        window?.layer.speed = 0
        // Disable UIView animations
        UIView.setAnimationsEnabled(false)
    }
    return true
}
2
Oliver Pearmain

DidFinishLaunchに追加します

[UIApplication sharedApplication].keyWindow.layer.speed = 2;

デフォルト値は1で、速度を2倍にするには2にします。

2

UITestsの時間を30%に減らし、すべての手順に従います。

アプリを実行するときに、引数を追加します。

let app = XCUIApplication()

override func setUp() {
    super.setUp()

    continueAfterFailure = false
    app.launchArguments += ["--Reset"]
    app.launch()
}

次に、AppDelegateに次を追加します。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    setStateForUITesting()
}

static var isUITestingEnabled: Bool {
    get {
        return ProcessInfo.processInfo.arguments.contains("--Reset")
    }
}

private func setStateForUITesting() {
    if AppDelegate.isUITestingEnabled {
        // If you need reset your app to clear state
        UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)

        // To speed up your tests
        UIApplication.shared.keyWindow?.layer.speed = 2
        UIView.setAnimationsEnabled(false)
    }
}

コードで、がテストモードかどうかを確認するには、次を使用できます。

if AppDelegate.isUITestingEnabled {
    print("Test Mode")
}

さらに、要素の読み込み中にwaitを実行するには、この拡張機能を作成しました。

import XCTest

extension XCUIElement {
    func tap(wait: Int, test: XCTestCase) {
        if !isHittable {
            test.expectation(for: NSPredicate(format: "hittable == true"), evaluatedWith: self, handler: nil);
            test.waitForExpectations(timeout: TimeInterval(wait), handler: nil)
        }
        tap()
    }
}

次のように使用します。

app.buttons["start"].tap(wait: 20, test: self)
1
Narlei Moreira

それらを並行して実行します。

ビルドマシンが1つしかない場合は、Bluepillを使用できます。 https://github.com/linkedin/bluepill

複数のマシンがある場合は、Emceeを使用できます: https://github.com/avito-tech/Emcee (単一のマシンのセットアップでも機能します)

50時間のUIテストがあり、Emceeでは1時間で実行できます。 UIテストを高速化するためのいくつかのトリックがありますが、それらを並行して実行しないと意味がありません。例えば。 25秒のテストを0.5秒で実行することはできません。


トリック:

  1. 再インストールせずにXCUIApplicationを実行します。
_XCUIApplication(
    privateWithPath: nil,
    bundleID: "your.bundle.id"
)
_

注:アプリをインストールするには、XCUIテストランナーを起動するたびにXCUIApplication().launch()でアプリを起動する必要があります。これにはプライベートAPIの使用が必要です。

  1. 何かをバックグラウンドスレッドに移動できます。例えば。
_let someDataFromApi = getSomeData() // start request asynchronously and immediately return
launchApp() // this can be few seconds
useInTest(someDataFromApi) // access to data will wait request to finish
_

非同期のものがないようにコードを見せれば、QAの方が簡単になります。これを実装したいのですが、実装しなかったので、アイデアにすぎません。

  1. EarlGreyに切り替えて、数秒続くテストを行います(ただし、ブラックボックスにはなりません)。

  2. ディープリンクがある場合は、ディープリンクを介して画面を開きます。

  3. プライベートAPIやその他のハックをたくさん使用します。例:UIから設定アプリに移動してプライバシー設定をリセットする代わりに、プライベートAPIを呼び出すことができます。

  4. 長い睡眠を決して使用しないでください。ポーリングを使用します。

  5. アニメーションを高速化します。それらを無効にしないでください!

  6. UIテストからアプリにいくつかのフラグを渡して、最初のアラート/チュートリアル/ポップアップをスキップします。多くの時間を節約できます。これらのアラートが機能することを確認するテストが少なくとも1つあることを確認してください。

1
artyom.razinov