準備
Playwrightでネイティブアプリをテストするには、以下の準備が必要。
Android Studioのインストール
adbコマンドなどのエミュレータ操作に必要なAndroid SDK Platform Toolsをインストールするため、Android Studioをインストールする。
Android Studioをダウンロードして起動すると必要なツールは自動でインストールされる。
エミュレータか実機の準備
Androidエミュレータか実機を用意する。
エミュレータを使う場合はAndroid Studioをインストールしてエミュレータを起動するのが簡単。
Playwrightプロジェクトの作成
Playwrightプロジェクトを作成する。
npm init playwright@latest
メッセージに従ってプロジェクトを作成する。
本記事では言語にTypeScriptを選択し、テストコードを格納するディレクトリにはtests
を指定する。
設定ファイルの修正(playwright.config.ts)
Playwrightの設定ファイルplaywright.config.ts
を修正する。
projects
にAndroidの設定を追加する。
projects: [
{
name: 'android-emulator'
}
],
ドライバのインストール
以下のコマンドを実行する。
npx playwright install android
テスト対象プログラムの作成
本記事では確認のため、Android Studioでテストアプリを作成する。
既存アプリがある場合は不要。
パッケージ名はcom.example.sampleapp
、アプリ名はSampleApp
とする。
テンプレートはBasic Views Activity
を選択する。
生成されたプロジェクトをエミュレータか実機で実行しておく。
Basic Views Activity
は2画面から構成され、起動した画面のNextボタンをタップすると次の画面に遷移し、Previousボタンをタップすると前の画面に戻る。
テストコードの作成
tests
ディレクトリにテストコードを作成する。
プロジェクトinit時にtests/example.spec.ts
が作成されているので、そのファイルを修正する。
import { test, _android, expect } from '@playwright/test';
test('サンプルテスト', async ({ }) => {
const [device] = await _android.devices();
// アプリを落としてから起動
await device.shell('am force-stop com.example.sampleapp');
await device.shell('am start com.example.sampleapp/.MainActivity');
await device.wait({ enabled: true });
// スクリーンショットを保存する
await device.screenshot({ path: 'images/sample1.png' });
// Nextボタンをタップ
await device.tap({
text: 'Next',
clickable: true,
})
await device.wait({ enabled: true });
// Previousボタンが表示されていることを確認
await expect(
(await device.info({ res: 'com.example.sampleapp:id/button_second' })).text
).toContain('Previous');
// スクリーンショットを保存する
await device.screenshot({ path: 'images/sample2.png' });
// Previousボタンをタップ
await device.tap({
text: 'Previous',
clickable: true,
})
await device.wait({ enabled: true });
// Nextボタンが表示されていることを確認
await expect(
(await device.info({ res: 'com.example.sampleapp:id/button_second' })).text
).toContain('Previous');
// スクリーンショットを保存する
await device.screenshot({ path: 'images/sample3.png' });
});
アプリの起動
以下のコードでアプリを起動している。
await device.shell('am force-stop com.example.sampleapp');
await device.shell('am start com.example.sampleapp/.MainActivity');
await device.wait({ enabled: true });
既にアプリが起動しているとエラーになるので、am force-stop
コマンドでアプリを落としてから起動している。
引数にはアプリのパッケージ名を指定する。
今回はプロジェクト作成時にcom.example.sampleapp
を指定したのでこのパッケージ名を指定している。
既存のアプリなどで端末にインストールされているパッケージ名の一覧は以下のコマンドで確認できる。
adb shell pm list packages
am start
コマンドの引数には<パッケージ名>/<アクティビティ名>
を指定する。
アクティビティ名はAndroidManifest.xml
の<application>
タグ内の<activity>
タグのandroid:name
属性の値を確認する。Basic Views Activity
の場合はMainActivity
が指定されている。
waitメソッドで待たせないとアプリが起動する前に次の処理が実行されるため、アプリが起動するまで待機させている。
スクリーンショットの保存
スクリーンショットを保存するにはscreenshot
メソッドを使用する。
await device.screenshot({ path: 'images/sample1.png' });
呼び出したタイミングの端末の画面をスクリーンショットとしてpath
に指定したパスへ保存する。
画面操作
tap
メソッドで画面をタップする。
await device.tap({
text: 'Next',
clickable: true,
})
await device.wait({ enabled: true });
ta@
メソッドの引数にはタップしたい要素を指定する。
引数の型はAndroidSelector
で以下のように定義されている。
export type AndroidSelector = {
checkable?: boolean,
checked?: boolean,
clazz?: string | RegExp,
clickable?: boolean,
depth?: number,
desc?: string | RegExp,
enabled?: boolean,
focusable?: boolean,
focused?: boolean,
hasChild?: { selector: AndroidSelector },
hasDescendant?: { selector: AndroidSelector, maxDepth?: number },
longClickable?: boolean,
pkg?: string | RegExp,
res?: string | RegExp,
scrollable?: boolean,
selected?: boolean,
text?: string | RegExp,
};
今回はNext
ボタンが現れるまでを条件とした。
タップ後はwait
メソッドで次の画面が表示されるまで待たせている。
tap
以外のメソッドについては APIドキュメント(AndroidDevice | Playwright)
を参照。
アサーション
expect
メソッドでアサーションを行う。
await expect(
(await device.info({ res: 'com.example.sampleapp:id/button_second' })).text
).toContain('Previous');
info
メソッドで指定した要素の情報を取得できる。
引数はtap
メソッドと同じくAndroidSelector
を指定する。
ここではres
でリソースIDを指定している。
テストの実行
以下のコマンドでテストを実行する。
npx playwright test
成功すれば以下のようなメッセージが表示される。
Running 1 test using 1 worker
1 passed (3.0s)
To open last HTML report run:
npx playwright show-report