TL;DR
FirebaseAuthenticationを用いたアプリの自動テスト時のreCAPTCHAを回避するにはappVerificationDisabledForTestingをTRUEにする
環境
- Xcode10.1
- Swift4.2
- XCTest
FirebaseAuthenticationにおけるiOSシミュレータ実行時のreCAPTCHAでコケる問題
FirebaseAuthenticationを利用した認証を利用しているアプリは多いと思いますが、iOSシミュレータで実行する際には認証時にreCAPTCHAを要求されます。自動テストを行うにあたって、reCAPTCHAは大きな壁です。
ローカルのmacでXCUITestで実行していた際にはあまり気にならなかったのですが(タイミングの問題もあるかと思いますが)、fastlane snapshotやFirebase Test Labなどで実行する際にほぼ100%失敗してしまい、頭を抱えていました。
解決方法:verifyPhoneNumberを呼び出す前にappVerificationDisabledForTestingを TRUEに設定
悩んだ挙げ句に公式ドキュメントを確認したところ、解消方法が記載されていました。堂々と記載されており、恥ずかしい気持ちでいっぱいです。
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()