LoginSignup
2
1

More than 5 years have passed since last update.

FirebaseAuthenticationを用いたアプリの自動テスト時におけるreCAPTCHA回避方法

Posted at

TL;DR

FirebaseAuthenticationを用いたアプリの自動テスト時のreCAPTCHAを回避するにはappVerificationDisabledForTestingをTRUEにする

環境

  • Xcode10.1
  • Swift4.2
  • XCTest

FirebaseAuthenticationにおけるiOSシミュレータ実行時のreCAPTCHAでコケる問題

FirebaseAuthenticationを利用した認証を利用しているアプリは多いと思いますが、iOSシミュレータで実行する際には認証時にreCAPTCHAを要求されます。自動テストを行うにあたって、reCAPTCHAは大きな壁です。
スクリーンショット 2018-12-20 18.24.04.png

ローカルのmacでXCUITestで実行していた際にはあまり気にならなかったのですが(タイミングの問題もあるかと思いますが)、fastlane snapshotやFirebase Test Labなどで実行する際にほぼ100%失敗してしまい、頭を抱えていました。

解決方法:verifyPhoneNumberを呼び出す前にappVerificationDisabledForTestingを TRUEに設定:smiley:

悩んだ挙げ句に公式ドキュメントを確認したところ、解消方法が記載されていました。堂々と記載されており、恥ずかしい気持ちでいっぱいです。

iOS では、verifyPhoneNumber を呼び出す前に appVerificationDisabledForTesting 設定を TRUE に設定する必要があります。これは、バックグラウンドで APN トークンを要求したりサイレント プッシュ通知を送信することなく処理されたりするため、シミュレータでのテストが容易になります。これにより、reCAPTCHA フォールバック フローも無効になります。

let phoneNumber = "+16505554567"

// This test verification code is specified for the given test phone number in the developer console.
let testVerificationCode = "123456"

Auth.auth().settings.isAppVerificationDisabledForTesting = TRUE
PhoneAuthProvider.provider().verifyPhoneNumber(phoneNumber, uiDelegate:nil) {
                                                            verificationID, error in
    if (error) {
      // Handles error
      self.handleError(error)
      return
    }
    let credential = PhoneAuthProvider.provider().credential(withVerificationID: verificationID ?? "",
                                                               verificationCode: testVerificationCode)
    Auth.auth().signInAndRetrieveData(with: credential) { authData, error in
      if (error) {
        // Handles error
        self.handleError(error)
        return
      }
      _user = authData.user
    }];
}];

上記の対応であの忌々しいreCAPTCHAの画面に遷移することなく認証が可能になります。ただし、ホワイトリストに登録済の電話番号しか認証できなくなるため、その点は要注意です。

自動テスト実行時のみに有効にする

このままだとマニュアルテスト時に利用するアプリでも登録済の電話番号しか使用できなくなるため、自動テストのみこの動作を行うようにします。
こちらの投稿を参照し、UITestの実行時のみ、このコードが有効になるように分岐させます。

プロダクトのコード

#if DEBUG || ADHOC
if ProcessInfo.processInfo.arguments.contains("UITEST") {
    Auth.auth().settings?.isAppVerificationDisabledForTesting = true
}
#endif

テストのコード

UITest起動時に launchArguments でUITESTの文字列を渡します。

let app = XCUIApplication()
app.launchArguments.append("UITEST")
app.launch()
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1