AWS Device Farm + Appium のWebブラウザテストを iOS環境でも動作するようにしてみた

2021.07.07

いわさです。

前回は Appium + Android のWebブラウザテストのコードを AWS Device Farm上で実行しました。

今回は iOSで実行してみました。

まずはAndroidのテストそのまま実行

前回のテストコードから変更なしで、テスト実行デバイスのみiOSに変更して実施してみます。

動きませんでした。
途中でテストが中断されています。

問題の対処を行っていきたいと思います。
トラブルシューティングではないですが、Device Farm上でトライ&エラーを繰り返すより、一旦ローカルのAppium環境で安定動作するようにテストコードを調整するほうがアプローチとしては速いことが多いです。

ローカルAppiumで動作確認

iOSシミュレーター実行

Appium+iOSをローカル実行するにあたって、iOSシミュレーターを使ってみたいと思います。
シミュレーターの利用にあたり、Xcodeのインストールが前提です。

シミュレーターはXcodeからも実行出来ますが、今回はCLIからシミュレーターを起動しました。

iwasa.takahito@xxx appium-web-browser % instruments -s devices
`instruments` is now deprecated in favor of 'xcrun xctrace' (see `man xctrace` for more information on its replacement)
Known Devices:
xxx [441B6B9C-3815-58DB-876E-32C40D11307A]
Apple TV (14.5) [F69C270D-A771-4CE1-821B-14CEE0299F2A] (Simulator)
Apple TV 4K (2nd generation) (14.5) [5DC5E7AB-7D85-48EE-B3BA-2D2FEC18A486] (Simulator)
Apple TV 4K (at 1080p) (2nd generation) (14.5) [7AD7A8B4-FF3E-4C0F-AF31-081E81339979] (Simulator)
iPad (8th generation) (14.5) [F586A1E2-C3CD-42FA-ACA7-64C43C1D34E4] (Simulator)
iPad Air (4th generation) (14.5) [DA196E9E-FC8D-439D-AEB9-ACA123F8892F] (Simulator)
iPad Pro (11-inch) (3rd generation) (14.5) [2073FBB0-92CB-4F3D-8B4E-40168A1DD46E] (Simulator)
iPad Pro (12.9-inch) (5th generation) (14.5) [9F5987F6-1047-45A1-8549-3D7838B91C6C] (Simulator)
iPad Pro (9.7-inch) (14.5) [F4817E35-A036-4E2F-A46B-CF972877D399] (Simulator)
iPhone 11 (14.5) [53EB3B5C-F78D-4270-8F06-0A55993E5EE8] (Simulator)
iPhone 11 Pro (14.5) [1E7C28A6-36CB-4012-89FD-4D57D63C02D8] (Simulator)
iPhone 11 Pro Max (14.5) [D81CE61A-EBD4-4F02-8813-0B4B312BFF8E] (Simulator)
iPhone 12 (14.5) [277E5E07-39F5-4B8F-A26B-313170087ED3] (Simulator)
iPhone 12 (14.5) + Apple Watch Series 5 - 44mm (7.4) [F625453C-C446-4C1B-B8FE-76F746A1FF0B] (Simulator)
iPhone 12 Pro (14.5) [6BE85E04-E61C-4480-B430-18233941E1E1] (Simulator)
iPhone 12 Pro (14.5) + Apple Watch Series 6 - 40mm (7.4) [6C20FC5D-2404-4830-827F-71A797D341AB] (Simulator)
iPhone 12 Pro Max (14.5) [FD5FBB24-7EB7-4E66-AACB-1FC37F234AE8] (Simulator)
iPhone 12 Pro Max (14.5) + Apple Watch Series 6 - 44mm (7.4) [B3B9B0C7-1774-4911-93EA-00E0BBFA95F4] (Simulator)
iPhone 12 mini (14.5) [16F69E5A-1A80-4265-B2C4-54D0C3611E1C] (Simulator)
iPhone 12 mini (14.5) + Apple Watch Series 5 - 40mm (7.4) [D77A94E8-EEEC-4557-8579-A1085E23DE33] (Simulator)
iPhone 8 (14.5) [42075021-5A4B-41BB-AF1F-C0FB6F9770B3] (Simulator)
iPhone 8 Plus (14.5) [C5046C42-1C5D-47CE-BAF1-68E329E020DD] (Simulator)
iPhone SE (2nd generation) (14.5) [B1118467-9317-4FCA-A832-F901BE23FB25] (Simulator)
iPod touch (7th generation) (14.5) [C6FA87EE-E16C-407D-8D36-59FFA76AC27C] (Simulator)
iwasa.takahito@HL00780 appium-web-browser %

シミュレーター一覧が取得出来ました。
今回は、iPhone8で実行してみたいと思います。

iwasa.takahito@xxx appium-web-browser % xcrun instruments -w 'iPhone 8 (14.5)'
`instruments` is now deprecated in favor of 'xcrun xctrace' (see `man xctrace` for more information on its replacement)
instruments[10184]: Waiting for device to boot...
Instruments Usage Error: No template (-t) specified
instruments, version 12.5.1 (64544.132)
usage: instruments [-t template] [-D document] [-l timeLimit] [-w device] [-P package] [[-p pid] | [application [-e variable value] [argument ...]]]
iwasa.takahito@xxx appium-web-browser %

シミュレーターが起動されました。

Appiumの実行にあたって、SafariのWebインスペクターが有効化されている必要があります。
ただし、iOSシミュレーターはデフォルトで有効化されています。

実機の場合は以下2点を実施する必要がありますので忘れずに対応をしてください。

  • Web Inspector を有効化
  • ios-webkit-debug-proxy を使って、マシンを信頼させる

Webインスペクターが有効化されていると、macOS側のSafariからシミュレーター側Safariの要素へアクセスできるようになります。

iOS用にCapabilitiesの修正

iOSのSafariで実行出来るよう、Capabilitiesへ以下のコードを追加します。

platformName: "iOS",
platformVersion: "14.5",
deviceName: "iPhone 8",
browserName: "Safari",
automationName: "XCUITest"

実行と調整

環境作成とコード修正が完了したので、テストを実行します。
実行途中でテストが止まりました。

ログを確認すると、touchScrollメソッドでエラーとなっています。
iOS-XCTestの場合はclickで自動でスクロールする仕様になっているため、touchScroll部分は除外して実行します。

最終的なコードは以下のように調整しました。
※ローカル実行なのでスクリーンショット取得部分はコメントアウトするか、パスの修正が必要です。

index.js

const wdio = require("webdriverio");
const assert = require("assert");

const opts = {
  path: '/wd/hub',
  port: 4723,
  capabilities: {
    // platformName: "Android",
    // platformVersion: "9",
    // deviceName: "Android Emulator",
    // browserName: "Chrome",
    // automationName: "UiAutomator2"
    platformName: "iOS",
    platformVersion: "14.5",
    deviceName: "iPhone 8",
    browserName: "Safari",
    automationName: "XCUITest"
  }
};

const DEFAULT_TIMEOUT = 15000;
const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
async function main () {
  const client = await wdio.remote(opts);

  await client.url("https://classmethod.jp/");

  const menuButton = await client.$(".header__menu");
  await menuButton.waitForDisplayed({timeout: DEFAULT_TIMEOUT});
  await sleep(3000);
  await client.saveScreenshot(process.env.SCREENSHOT_PATH + "/1.png");

  await menuButton.click();

  await sleep(2000);
  //await client.touchScroll(0, 500);
  await sleep(1000);

  const siryoButton = await client.$('a[href="/download/company-overview/"]');
  await siryoButton.waitForDisplayed({timeout: DEFAULT_TIMEOUT});
  await client.saveScreenshot(process.env.SCREENSHOT_PATH + "/2.png");

  await siryoButton.click();
  await sleep(5000);
  await client.saveScreenshot(process.env.SCREENSHOT_PATH + "/3.png");

  await sleep(10000); //add

  await client.deleteSession();
}

main();

テストが期待どおり動いたので、DeviceFarmで実行していきたいと思います。

Device Farmで実行

Device Farmでの実行にあたって、Androidと同様にCapabilities部分を空にする必要があります。
この点のみ修正を忘れないようにしてください。

また、現時点で Webブラウザテストでサポートされている iOSバージョンは 13.3.1 までとなっています。
デバイスプール上には iOS13.5 や iOS14 などが普通に存在していますのでデバイスの選択にも気をつけてください。

デバイスプールを選択したらテストを実行します。

touchScroll外すことでテストが進みました。
1画面目がロード中の白い画面のままです。
要素の表示を待つか、スリープを行うなど微調整しましょう。

Androidと同様に iOS Safari でも自動テストを実行することが出来ました。

まとめ

多少の調整は必要ですが、テストコードはほぼAndroidと共通で使うことが出来ました。

  • Androidで動いたコードが必ずしも動かない
    • XCTestなど挙動に差が出る仕様もある
    • WebDriver上でもプラットフォームによっては動作しないメソッドなどがある
  • ローカルAppiumで十分調整した上で、DeviceFarm上の複数デバイスで実行する