ENGINEER BLOG

ENGINEER BLOG

AWS Device FarmでスマホWebアプリのテストをしてみる

こんにちは、C&I統括本部テクノロジーイノベーションの朝日です。

今回はAWSのDevice Farmを使ってスマホでのWebアプリテストを実行してみます。

Working with web app tests in AWS Device Farmを参考に、Appiumを使っていきます。

Working with Appium and AWS Device Farmによると、テストコードを書くには

  • Java(JUnit)
  • Java(TestNG)
  • Python
  • Node.js
  • Ruby

が使えますので、今回はNode.jsを使ってみます。

※なお、記事執筆当時はAppium v1.xでもappium.ioからドキュメントが参照できたのですが、現在はリンク切れになっていたのでGithubのv1.xブランチのドキュメントへのリンクにしています。Device Farm中の情報がAppium v1.xベースだったので、本記事ではv2.xではなくv1.xを利用していますが、今後トライする方はぜひv2.xにチャレンジしてみてください。

環境

  • Node.js v16.20.0
  • Appium v1.22.3
  • WebdriverIO v8.8.2
  • npm-bundle v3.0.3

Android実機確認用

  • Android Studio Electric Eel (2022.1.1 Patch2)

Windows確認用

  • WinAppDriver v1.2.1
  • Windows 10

準備

Appiumの導入

Node.jsは導入してあるとして、まずはAppiumを導入します。

npm install -g appium

WebdriverIOの導入

次に、テストコードを格納するための任意のディレクトリを作成し、WebdriverIOを導入します。

mkdir testcode
cd testcode
npm init -y
npm install webdriverio

テストコードを書く

いきなりモバイル用のテストを書き始めても良いのですが、ある程度Windows上のChromeで動作確認してから進めます。
Windows上でテストするにはWinAppDriverが必要になるのでインストールしておきます。

Getting Startedなどを参考にテストコードを書いていきます。 若干Windows用に変更して、以下のような内容のindex.jsを作成します。

const wdio = require("webdriverio");

const opts = {
    capabilities: {
        platformName: 'Windows',
        browserName: 'Chrome',
        'goog:chromeOptions': {
            args: ['--window-size=600,1024']
        }
    }
};

async function main() {
    const client = await wdio.remote(opts);

    await client.url('https://techceed-inc.com/');
    await client.pause(3 * 1000);
    await client.saveScreenshot('./img01.png')

    const sp_btn = await client.$('.sp_btn');
    await sp_btn.click();
    await client.pause(3 * 1000);
    await client.saveScreenshot('./img02.png')

    await client.deleteSession();
}

main();

clientで使えるメソッドはWebdriverIOの情報を参考にしてください。
簡単なので読めばわかると思いますが、弊社のホームページを表示して、右上のメニューボタンを押し、都度スクリーンショット画像を撮るというだけのテストコードです。 なお、スマホレイアウトでテストコードを動かしたかったのでウィンドウサイズを小さくするように指定しています。

作成したら、

node index.js

でテスト実行です。

こんな感じでスクリーンショットが取得できていれば無事テストコードが動いています。

スマホ実機(Android)を使ってテストする

無事テストコードの動作が確認できたので、次はAndroid実機をUSBで繋いでテストしてみます。
Android SDKおよびJREが必要となるため、Android Studioをインスト-ルしておきます。

ANDROID_HOMEおよびJAVA_HOMEの環境変数が設定されていない場合は、以下を実行してから作業します。

set ANDROID_HOME=%USERPROFILE%\AppData\Local\Android\Sdk
set JAVA_HOME=C:\Program Files\Android\Android Studio\jbr

テストコードについては、mainは変更しなくても良いのですが、optsの部分はAndroid用に変更します。

const opts = {
    path: '/wd/hub',
    port: 4723,
    capabilities: {
        platformName: 'Android',
        browserName: 'Chrome',
        automationName: 'UiAutomator2'
    }
};

Appiumサーバーを起動してからテストコードを実行します。

start appium
node index.js

もしも下記のようなエラーが出てしまった場合は、

Encountered internal error running command: Error: No Chromedriver found that can automate Chrome '112.0.5615'. You could also try to enable automated chromedrivers download server feature. See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/web/chromedriver.md for more details

Automatic Discovery of Compatible Chromedriverに従って、下記のようにChromedriverの自動検出機能を有効にしてサーバーを起動します。

start appium --allow-insecure chromedriver_autodownload

これでAndroid実機でもテストコードが動くことが確認できました。

Device Farmでテストする

最後に、本命であるDevice Farmでテストしてみます。

Device Farmでテストするためには、以下の作業が必要です。

テストコードの修正

Device Farm用にテストコードを以下2点修正します。

  • capabilitiesを空にします。
  • DEVICEFARM_SCREENSHOT_PATH環境変数を参照して、そこにスクリーンショットを保存するように変更します。 
    参照:Take screenshots of your tests (Optional)
const wdio = require("webdriverio");

const opts = {
    path: '/wd/hub',
    port: 4723,
    capabilities: {
    }
};

async function main() {
    const client = await wdio.remote(opts);

    await client.url('https://techceed-inc.com/');
    await client.pause(3 * 1000);
    await client.saveScreenshot(process.env.DEVICEFARM_SCREENSHOT_PATH+'/img01.png')

    const sp_btn = await client.$('.sp_btn');
    await sp_btn.click();
    await client.pause(3 * 1000);
    await client.saveScreenshot(process.env.DEVICEFARM_SCREENSHOT_PATH+'/img02.png')

    await client.deleteSession();
}

main();

テストパッケージファイルの作成

次に、作成したテストコードをnpm-bundleでまとめます。

npm install -g npm-bundle
cd ..
npm-bundle testcode

作成されたtgzファイルをさらにzip圧縮します。

Device Farmにアップロードしてテスト実行

Device Farmのコンソールでプロジェクトを作成したら、[Create a new run]で新しくテストを追加します。

Choose applicationでは”Web App”を選びます。

Configureでは”Appium Node.js”を選択して、先ほど作成したzipファイルをアップロードします。

続けて、[Create a TestSpec]でTestSpecを修正します。

今回使用したNode.jsのバージョンが16.20.0なので、そちらを導入するように変更します。

また、実行するテストコードのファイル名が”YOUR_TEST_FILENAME.js”になっているので”index.js”に変更し、ファイル名を指定して保存します。

次はテスト対象のデバイスプールを選択します。 デフォルトで選択されている”Top Devices”のまま実行してしまうと10台でテストしてしまうので、[Create device pool]でテストしたいデバイスを絞っておいた方がよいでしょう。

Create device poolでは、特定の機種を選択したい場合は、”Create static device pool”を選択してから任意のデバイスを選定しましょう。

今回は、“Apple iPhone 14”、”Samsung Galaxy S23″の2つを選択しました。 [Next]ボタンを押して次の画面で[Comfirm and start run]ボタンを押すとテストスタートです。 ローカル環境ではすぐに終わるテストでもDevice Farm上ではかなりかかるのでゆっくり待ちましょう。

テストが完了したらコンソールでテスト結果の動画やスクリーンショットなどが確認できます。

以上となります。

さいごに

実は、今回最初はNode.jsのバージョンを最新LTSのv18.16.0で作業していたのですが、npm-bundleでうまくパッケージが作成されなかったので、1つ前のLTS v16.20.0を使用しました。 なにか異常があったときは、いちいちDevice Farmにアップロードして確認すると時間がかかるので、できるだけローカルで確認しておくと良いでしょう。

npm-bundleについても、出来上がったtgzファイルをDevice FarmのTest spec fileと同じように

npm install *.tgz
cd node_modules/*
npm list

と実行してみるとWebdriverIOが入っていないことがわかって解決しました。

うまくテストコードを書けば、実機を購入することなく様々なデバイスでテストできるので、活用していきたいですね。