見出し画像

Appiumでモバイルアプリのログイン部分の試験を自動化する

こんにちは、最近肩まわりが痛いのですが、筋トレの頑張りすぎかデスクワークのやりすぎか判別がつかないTamaです。

今回は試験自動化の鬼門であるログインの部分にチャレンジしてみたいと思います!


1. ログイン周りの試験自動化が難しい理由

  • ログインのプロセスがFirebaseを使っている場合は、自分で実装した要素ではなくGoogle側が定義するものなので自由にAccessbility ID等を設定できない

  • メールアドレスやパスワードなど、共有すべきでない情報を使う必要があるため、テストスクリプトの作成およびそれら情報の管理に気を使う必要がある

  • 2要素認証でシュミレータ外での想定できない操作 (認証番号の入力や他ログイン済みデバイスでの承認許可など)が必要になる

以上の関門をクリアしないといけないため、一番初めにやってくる試験であり、一番ハードルが高そうな試験とも言えそうです

2. ログイン確認モーダルのContinueボタンを押す

まずやってくるのが確認モーダルです。Appium Inspectorで確認したところ、Firebase側が提供しているモーダルだからか、UIの要素の詳細を取得できません

こちらをタップするにはこのiOSのアラートモーダルの仕様に従ってボタンの名前ではなくて、左側ボタンがdismissという操作、右側ボタンがacceptという操作であるということに従いスクリプトを記載する必要があります

以下のラインで右側の「Continue」ボタンを押すことができます

self.driver.switch_to.alert.accept()

3.アカウントを選択する

ログイン済みのアカウントを選ぶ

すでにシュミレーターでログイン済みのアカウントがある場合は以下のように特定のアカウント名とメールアドレスで指定します。
(※冒頭で記載したようにこのようにベタ書きでアカウント情報などをテストのスクリプト内に含めるのは望ましくないので他記事で対応記載します)

アカウント名とメールアドレスは書き換えてください

element = self.driver.find_element(By.XPATH, '//XCUIElementTypeLink[@name="YourAccountName yourgmailadress@gmail.com"]')
element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'Continue')
element.click()

新しくGoogleアカウントでログインする

上記の部分を以下のように書き換えます

element = self.driver.find_element(By.XPATH, '//XCUIElementTypeOther[@name="ログイン - Google アカウント"]/XCUIElementTypeOther[4]/XCUIElementTypeOther[2]')
        element.click()
        time.sleep(3)

        # find the email input field and input the email by not accessibility id
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeTextField')
        element.send_keys('yourmailaddress@gmail.com') 
        element.send_keys(Keys.RETURN)
        time.sleep(3)

        # find the password input field and input the password
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeSecureTextField')
        element.send_keys('yourpassword')
        element.send_keys(Keys.RETURN)
        time.sleep(5)

これでログインはできるようになりました!

次の記事では以下も対応していこうと思います

  • ログインするときに2要素認証が飛んだ時の対応

  • テストを何回も実行することに備えて必要に応じてログイン情報の削除


4. フルのテストスクリプト

ログイン済みのアカウントを選ぶ場合

import time
import unittest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.ios import XCUITestOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

class IOSAppiumTest(unittest.TestCase):
    def setUp(self):
        # Define desired capabilities
        options = XCUITestOptions()
        options.platform_name = 'iOS'
        options.platform_version = '18.2'  # Replace with your iOS version
        options.device_name = 'iPhone 16 Pro'  # Replace with your device name
        options.app = 'path/to/your.app'  # Replace with the path to your app
        options.automation_name = 'XCUITest'

        # Initialize the driver
        self.driver = webdriver.Remote('http://localhost:4723', options=options)

    def test_example(self):
        # Find google login button and click it
        element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'GIDSignInButton')
        element.click()

        # click on the button on the iOS alert
        self.driver.switch_to.alert.accept()
        time.sleep(3)

        # for logged in account
        # click one of the account
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeLink[@name="YourAccountName youraddress@gmail.com"]')
        # click the Continue button
        element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'Continue')
        element.click()
        time.sleep(3)

    def tearDown(self):
        # Quit the driver
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

新しくGoogleアカウントでログインする

import time
import unittest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from appium.options.ios import XCUITestOptions
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

class IOSAppiumTest(unittest.TestCase):
    def setUp(self):
        # Define desired capabilities
        options = XCUITestOptions()
        options.platform_name = 'iOS'
        options.platform_version = '18.2'  # Replace with your iOS version
        options.device_name = 'iPhone 16 Pro'  # Replace with your device name
        options.app = 'path/to/your.app'  # Replace with the path to your app
        options.automation_name = 'XCUITest'

        # Initialize the driver
        self.driver = webdriver.Remote('http://localhost:4723', options=options)

    def test_example(self):
        # Find google login button and click it
        element = self.driver.find_element(AppiumBy.ACCESSIBILITY_ID, 'GIDSignInButton')
        element.click()

        # click on the button on the iOS alert
        self.driver.switch_to.alert.accept()
        time.sleep(3)

        # for not logged in account
        # click new login button
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeOther[@name="ログイン - Google アカウント"]/XCUIElementTypeOther[4]/XCUIElementTypeOther[2]')
        element.click()
        time.sleep(3)

        # find the email input field and input the email by not accessibility id
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeTextField')
        element.send_keys('youremailadress@gmail.com') 
        element.send_keys(Keys.RETURN)
        time.sleep(3)

        # find the password input field and input the password
        element = self.driver.find_element(By.XPATH, '//XCUIElementTypeSecureTextField')
        element.send_keys('yourpassword')
        element.send_keys(Keys.RETURN)
        time.sleep(5)

    def tearDown(self):
        # Quit the driver
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

いいなと思ったら応援しよう!