mcpField
I
injecting-input-and-state

injecting-input-and-state

github.com/skydovesテスト・品質33972 回インストール22 週間前に更新
リポジトリ

injecting-input-and-state について

Android のテスト担当者向けに、ADB Shell で端末を操作するスキルです。入力のシミュレーション、画面やシステム設定、アプリ状態のリセット、Activity 起動を扱い、`cmd` と従来の方法の違いも説明します。

主な機能

  1. 01input によるジェスチャー、文字、キーの入力
  2. 02wm による画面サイズと密度の変更
  3. 03settings によるテスト状態の設定
  4. 04force-stop とアプリデータ消去の区別
  5. 05am と cmd による起動やサービス制御

活用シーン

  1. 01CI で端末操作をスクリプト化
  2. 02画面サイズ、密度、システム設定の違いをテスト
  3. 03テスト実行間のアプリ状態リセット
  4. 04Intent extras 付きのディープリンク起動

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/skydoves/android-testing-skills --skill injecting-input-and-state

インストール後、Claude Code で/injecting-input-and-stateを入力して読み込まれたか確認します。

詳細

入力と状態の注入 — シェルからデバイスを操作する

このスキルでは、テスト/QA エンジニアが adb 経由で操作するオンデバイスのシェル機能を扱います。ユーザー操作のシミュレーション、画面構成の上書き、システム設定の切り替え、アプリ状態のリセット、Activity の起動ができます。トランスポート(adb devices、USB/TCP)については ../../architecture/understanding-adb-architecture/SKILL.md を、デバイス操作後の成果物のキャプチャについては ../../capture/capturing-screenshots-and-screenrecord/SKILL.md を参照してください。

このスキルを使う場面

  • 開発者が、インストルメンテーションを書かずに、CI からユーザージャーニー(タップ、スワイプ、テキスト入力、ハードウェアキーの押下)をスクリプト化する必要がある場合。
  • バグの再現に特定の画面サイズや密度(wm size 411x731、wm density 320)が必要で、エミュレーター AVD を再作成したくない場合。
  • アニメーションが有効なためにテストスイートが不安定になり、開発者が標準的な独立実行用の事前設定(window_animation_scale = 0 など)を求めている場合。
  • 開発者が実行間にアプリデータを消去する必要があるものの、am force-stop で十分かどうか分からない場合(十分ではありません)。
  • スクリプトで adb shell svc wifi disable を実行しても API 30 以降では何も起きず、最新の cmd wifi set-wifi-enabled disabled で解決する場合。
  • 開発者が型付きの追加情報(--ez、--ei、--es)を指定してディープリンク Activity を起動する必要がある場合。

このスキルを使わない場面

  • バイト列をデバイスの外に取り出す必要がある場合(スクリーンショット、ログ、DB)。../../capture/capturing-screenshots-and-screenrecord/SKILL.md、../../observability/extracting-logs-with-logcat/SKILL.md、../../transfer/extracting-test-artifacts/SKILL.md を参照してください。
  • ホストからではなく、インストルメンテーションテスト内からデバイスを操作する場合。../../../instrumentation/scenarios/launching-activities-with-activityscenario/SKILL.md または UiAutomator を使ってください。
  • APK をインストールまたはアンインストールする場合。../../apps/installing-and-managing-apps/SKILL.md を参照してください。
  • まずデバイスに接続する場合。../../devices/connecting-to-devices/SKILL.md または ../../devices/connecting-over-wifi/SKILL.md を参照してください。

前提条件

  • 到達可能なデバイスまたはエミュレーター(adb get-state が device を返すこと)。
  • ホストに Platform Tools 23 以降がインストールされていること。Platform Tools 23 以降では、adb shell を介したクォートは(ssh 形式の)二重シェルになるため、スペースを含む文字列では重要です(developer.android.com/tools/adb#shellcommands)。
  • cmd ラッパー API と信頼性の高いシェル終了コードを使うには、デバイスが API 24 以降であること(cmd は API 24 で導入)。

input — 合成ユーザーイベント

input は、デバイス上で InputManager.injectInputEvent() を呼び出すラッパーです。完全な文法は次のとおりです。

input [<source>] <command> [<arg>...]

<source> はコマンドごとに既定値が異なります(tap/swipe はタッチスクリーン、text/keyevent はキーボード)。

タップ、スワイプ、ドラッグアンドドロップ
adb shell input tap <x> <y>
adb shell input swipe <x1> <y1> <x2> <y2> [<duration_ms>]
adb shell input draganddrop <x1> <y1> <x2> <y2> [<duration_ms>]
adb shell input roll <dx> <dy>                        # rotary/trackball axes
adb shell input motionevent <DOWN|UP|MOVE|CANCEL> <x> <y>

<duration_ms> を省略した場合、swipe の既定値は約 300 ms です。長押しを合成するには、長押しタイムアウトの間、同じ位置でスワイプします。例:input swipe <x> <y> <x> <y> 1000。draganddrop は swipe と異なり、View.OnDragListener が受け取れるドラッグアンドドロップのジェスチャーシーケンス(DOWN → MOVE → UP)を発生させます。swipe と同じイベントストリームではありません。

テキスト入力 — クォートの落とし穴
adb shell input text "<string>"

注意点(developer.android.com/tools/adb より):

  • スペースは必ず %s としてエンコードする必要があります。 input text "hello world" を実行すると、hello と入力された後、何も入力されません。
  • シェルのメタ文字('、"、&、(、)、<、>、|、;、\、バッククォート)は、ローカルシェルとデバイス側シェルのそれぞれで、一度ずつ、合計二度エスケープする必要があります。
  • 非 ASCII 文字/Unicode は input text では正常に動作しないことがあります。その場合は UiAutomator の UiObject2.setText(...) を使ってください。
キーイベント
adb shell input keyevent [--longpress|--doubletap] <KEYCODE> [<KEYCODE>...]
adb shell input keyevent <NUMERIC_CODE>

テストに関連する KEYCODE_*(frameworks/base の KeyEvent 定数。全一覧は調査ノート A2 を参照してください):

ニーモニック数値備考
KEYCODE_HOME3ホームボタンを押します(画面が常に点灯するとは限りません)。
KEYCODE_BACK4戻るボタンです。
KEYCODE_DPAD_UP/DOWN/LEFT/RIGHT/CENTER19-23テレビ/フォーカス移動用です。
KEYCODE_VOLUME_UP/DOWN/MUTE24/25/164
KEYCODE_POWER26画面のオン/オフを切り替えます。
KEYCODE_TAB61
KEYCODE_ENTER66
KEYCODE_DEL67バックスペースです。
KEYCODE_MENU82
KEYCODE_APP_SWITCH187最近使ったアプリボタンです。
KEYCODE_WAKEUP224ロックを解除せずに画面を点灯します。
KEYCODE_SLEEP223強制的にスリープ状態にします。

ロックのないエミュレーターで画面を点灯し、キーロックを解除します:

adb shell input keyevent KEYCODE_WAKEUP
adb shell input keyevent 82                     # menu, dismiss the AOSP swipe-up
ソースプレフィックス

input <source> <command> は InputDevice.SOURCE_* に対応します。画面に複数の入力リスナーがある場合や、タッチ以外のハードウェアを対象とする場合は、ソースプレフィックスを指定します:

ソース主な用途
touchscreentap、swipe、draganddrop のデフォルトです。
touchpad外付けタッチパッド(Chromebook/Android タブレットのキーボード)用です。
dpadテレビ/フォーカス移動用です:input dpad keyevent KEYCODE_DPAD_DOWN。
keyboardtext、keyevent のデフォルトです。
mouseマウスボタンとスクロール用です。
trackballトラックボールの回転用です。
gamepad / joystickゲームパッドのボタン/ジョイスティックの軸用です。
stylus筆圧対応タッチ(S-Pen)用です。

wm — ディスプレイサイズと密度のオーバーライド

wm は IWindowManager のシェルラッパーです。テストに関連するサブコマンドは次のとおりです:

adb shell wm size                               # read current logical size
adb shell wm size 1080x1920                     # override
adb shell wm size reset                         # restore device default

adb shell wm density                            # read current dpi
adb shell wm density 320                        # override
adb shell wm density reset

adb shell wm dismiss-keyguard                   # insecure keyguard only
adb shell wm user-rotation [free|lock [<rotation>]]   # 0,1,2,3 = 0/90/180/270

使用例 — エミュレーターを再作成せずに、画面サイズ/密度の組み合わせをテストします:

# Per configuration in the matrix
adb shell wm size 411x731
adb shell wm density 240
# … run tests …
adb shell wm size reset
adb shell wm density reset

注意事項:

  • 必ず @AfterClass/スイートのティアダウンで reset を呼び出してください。呼び出さないと、実行後もデバイスが変更後の構成のままになり、後続の実行や人間のユーザーに影響します。
  • wm size/wm density は構成変更を引き起こし、フォアグラウンドの Activity を再作成します。テスト中ではなく、テスト間で使用してください。
  • am display-size/am display-density は同等の旧式の表記です。wm の使用を推奨します。

settings — テスト状態の分離

adb shell settings [--user <id>] get   <namespace> <key>
adb shell settings [--user <id>] put   <namespace> <key> <value> [<tag>] [default]
adb shell settings [--user <id>] delete <namespace> <key>
adb shell settings [--user <id>] reset <namespace> [<package>] [untrusted_defaults|untrusted_clear|trusted_defaults]
adb shell settings [--user <id>] list  <namespace>

<namespace> は global、system、secure のいずれかです。

分離されたテストの前処理 — アニメーション設定

計測テストとスクリーンショットテストを安定させるため、3 つすべてを 0 に設定します:

adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0

または、Gradle で testOptions.animationsDisabled = true を指定します。

その他のテスト関連キー
名前空間キー目的
systemfont_scale浮動小数点数(例:1.0、1.3)。文字サイズのテストに使用します。
secureaccessibility_enabledユーザー補助機能を有効にするには 1 を指定します。enabled_accessibility_services と組み合わせてください。
secureenabled_accessibility_servicesユーザー補助機能のテスト用に pkg/.Service を CSV 形式で指定します。
securedefault_input_method既知の IME を強制的に使用します。
secureshow_ime_with_hard_keyboardエミュレーターで IME を表示したままにするには 1 を指定します。
securelong_press_timeout長押しテストを安定させます。
globalairplane_mode_onam broadcast android.intent.action.AIRPLANE_MODE と組み合わせてください。
globalpolicy_control例:immersive.full=* を指定するとシステムバーを非表示にします。

アプリの状態 — am force-stop と pm clear の違い

コマンドプロセスを終了しますか?データ/キャッシュ/設定を消去しますか?ランタイム権限をリセットしますか?
am force-stop <pkg>はいいいえいいえ
pm clear <pkg>はい(暗黙的に)はいはい
cmd activity stop-app <pkg>はい(新しい API 28 以降)いいえいいえ

テスト間で状態を分離してリセットするには、pm clear を使用します。「プロセスを終了して次回の起動をコールドスタートにする」だけなら、am force-stop で十分です。pm の全コマンドについては ../../apps/installing-and-managing-apps/SKILL.md を参照してください。

アクティビティの起動 — am start

# Most reliable for tests: explicit component.
adb shell am start -n com.example.app/.MainActivity

# Force-stop first, then launch (clean cold start).
adb shell am start -S -W -n com.example.app/.MainActivity

# Launch by action + URI (default handler for https://).
adb shell am start -a android.intent.action.VIEW -d 'https://example.com'

# Pass typed extras.
adb shell am start -n com.example.app/.MainActivity \
  --es screen "settings" --ez debug true --ei count 42

# Return to launcher between tests.
adb shell am start -a android.intent.action.MAIN -c android.intent.category.HOME

Intent 指定子フラグ(developer.android.com/tools/adb#IntentSpec から抜粋):

トークン効果
-a actionIntent アクション(例:android.intent.action.VIEW)。
-d data_uriデータ URI。
-t mime_typeMIME タイプ。
-c categoryカテゴリ。
-n component明示的なコンポーネント(pkg/.Activity)。
-f flags16 進数の setFlags() 値。
`--es-e key value`
--ez key boolブール値の追加データ。
--ei key int整数の追加データ。
--el key longlong 型の追加データ。
--ef key floatfloat 型の追加データ。
--eu key uriURI の追加データ。
--ecn key componentComponentName の追加データ。
--eia/--ela/--efa key v[,v...]配列の追加データ。
--activity-clear-top などFLAG_ACTIVITY_* に対応します。
-S起動前に対象を強制停止します。
-W起動が完了するまで待機します。

cmd <service> — 最新のラッパー

cmd は、バインダーサービスの onShellCommand を呼び出す汎用ラッパーです。API 24 以降で利用できます。サービスを一覧表示するには、adb shell cmd -l(または dumpsys -l)を実行します。テストで関連するエントリーポイントは次のとおりです。

呼び出し効果
cmd activity stop-app <pkg>am force-stop に相当する最新のコマンドです。
cmd activity broadcast …am broadcast と同じです。
cmd package install -r -t -g <path>pm install に相当します。
cmd package compile -m speed -f <pkg>AOT コンパイルを強制します。
`cmd appops set allowdeny
cmd jobscheduler run -f <pkg> <jobId>JobService をただちに実行するよう強制します。
`cmd uimode night yesno
cmd locale set-app-locales <pkg> --locales en-USアプリごとのロケールを設定します(Android 13 以降)。
cmd statusbar expand-notifications / collapse通知シェードを展開/折りたたみます。
`cmd wifi set-wifi-enabled enableddisabled`
`cmd connectivity airplane-mode enabledisable`
cmd testharness enableデバイスを隔離されたテストハーネス状態にリセットします(Android 10 以降)。
API 30 以降での svc の非推奨化

svc data、svc wifi、svc bluetooth は、特権シェルから実行しない限り、API 30 以降では何もしません(corpus §I.10)。推奨される代替手段は、上記の cmd ラッパーです。

パターン

パターン:誤り — API 30 以降での svc wifi disable
# WRONG
adb shell svc wifi disable
# WRONG because: silently no-ops on API 30+ since the svc CLI was demoted from a privileged
# helper to an ordinary shell command. Exit code 0, Wi-Fi still on. The script proceeds
# under a wrong assumption — exactly the worst kind of failure mode.
# RIGHT
adb shell cmd wifi set-wifi-enabled disabled
adb shell cmd wifi status                       # verify
パターン:誤り — テスト間のリセットに am force-stop を使う
# WRONG
adb shell am force-stop com.example.app
./run-next-test.sh
# WRONG because: am force-stop kills the process but leaves shared prefs, databases, the
# image cache, and granted runtime permissions intact. The "next test" inherits state
# from the previous run.
# RIGHT
adb shell pm clear com.example.app
adb shell pm clear com.example.app.test         # also reset test process state
./run-next-test.sh

(Gradle 内では、clearPackageData: 'true' を指定した Test Orchestrator が同等の処理です。../../tests/running-instrumented-tests-via-adb/SKILL.md を参照してください。)

パターン:誤り — input text "hello world"
# WRONG
adb shell input text "hello world"
# WRONG because: spaces in `input text` MUST be encoded as %s. The above types only "hello".
# RIGHT
adb shell input text 'hello%sworld'
パターン:隔離されたテスト用の前処理 + Activity の起動
adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0
adb shell pm clear com.example.app
adb shell am start -S -W -n com.example.app/.MainActivity

-S は最初に強制停止します。-W は起動が完了するまで処理をブロックします。

パターン:D-pad によるテレビ/フォーカス操作
adb shell input dpad keyevent KEYCODE_DPAD_DOWN
adb shell input dpad keyevent KEYCODE_DPAD_DOWN
adb shell input dpad keyevent KEYCODE_DPAD_CENTER

dpad をソースとして指定することで、イベントがタッチスクリーンの処理経路ではなく、テレビ向けのフォーカスハンドラーに送られます。

必須ルール

  • API 30 以降では、必ず cmd wifi set-wifi-enabled/cmd connectivity airplane-mode/cmd bluetooth_manager enable を使用してください。svc wifi/svc bluetooth/svc data に依存してはいけません。これらは最新リリースでは何もせず、エラーも出ません。
  • テスト間で完全に隔離された状態にリセットする場合は、必ず pm clear <pkg> を使用してください(am force-stop ではありません)。force-stop はプロセスを終了するだけで、データには触れません。
  • input text の空白は必ず %s としてエンコードしてください。シェルのメタ文字を含む文字列は、(ssh 形式で)必ず二重にシェルクォートしてください。Platform Tools 23 以降(developer.android.com/tools/adb#shellcommands)。
  • スイートの後処理では、スイート内で上書きした場合、必ず wm size reset と wm density reset を呼び出してください。上書きが残ると、そのデバイスで後続の実行がすべて失敗します。
  • UI を検証するテストを実行する前に、3 つのアニメーションスケールを 0 に設定するか、Gradle で testOptions.animationsDisabled = true を使用してください。
  • UI が追いつくのを待つために、adb shell input の呼び出し間で Thread.sleep を使用してはいけません。インストルメンテーションテスト内では、Compose のアイドル同期を使用してください(../../../compose/synchronization/synchronizing-with-idle/SKILL.md)。ホストスクリプトからは、Activity の起動を待つために adb shell am start -W を使用し、再起動の合間には adb shell wait-for-device を使用してください。
  • -w を付けずに adb shell am instrument が意味のある終了コードを返すと想定してはいけません。../../tests/running-instrumented-tests-via-adb/SKILL.md および ../../automation/scripting-adb-for-ci/SKILL.md を参照してください。
  • 推奨: テストでコールドスタートする場合は am start -S -W -n pkg/.Activity を使用してください。-S はリセットし、-W は準備が完了するまで待機します。

検証

  • テスト実行前に adb shell settings get global window_animation_scale が 0(または 0.0)を返すこと。transition_animation_scale と animator_duration_scale についても同様です。
  • scripts/ または .github/workflows/ 内のスクリプトで svc wifi/svc bluetooth/svc data を使用していないこと。
  • テスト間のすべての am force-stop が pm clear と組み合わせて実行されているか、pm clear に置き換えられていること。
  • input text "<string with spaces>" が存在せず、すべての空白が %s になっていること。
  • セットアップにあるすべての wm size <override> に対し、後処理で wm size reset が実行されていること。
  • CI が「device entered prior config」による不安定な失敗なしで、連続 50 回の実行に成功すること。

参考資料

  • developer.android.com/tools/adb — am、pm、input、wm、settings、インテントの仕様(https://developer.android.com/tools/adb)。
  • developer.android.com/tools/adb#shellcommands — Platform Tools 23 以降の adb shell 経由の引用符の扱い。
  • developer.android.com/reference/android/view/KeyEvent — KEYCODE_* 定数の一覧表。
  • developer.android.com/training/testing/instrumented-tests/stability — アニメーションスケールをゼロにする標準的な手順。
  • developer.android.com/studio/test/advanced-test-setup#use-gradle-managed-devices — testOptions.animationsDisabled。
  • 調査メモ tasks/research/A2-adb-shell-commands.md — input/wm/settings/am/pm/cmd/svc の全テーブルと原文引用。
  • 関連スキル:../../architecture/understanding-adb-architecture/SKILL.md — 3 つの要素からなるアーキテクチャ、サーバー、デーモン。
  • 関連スキル:../../devices/connecting-to-devices/SKILL.md — adb devices の状態、wait-for-device。
  • 関連スキル:../../devices/connecting-over-wifi/SKILL.md — adb pair/adb connect。
  • 関連スキル:../../apps/installing-and-managing-apps/SKILL.md — pm install/pm uninstall/pm grant の全機能。
  • 関連スキル:../../tests/running-instrumented-tests-via-adb/SKILL.md — am instrument -w -r。
  • 関連スキル:../../capture/capturing-screenshots-and-screenrecord/SKILL.md — デバイスを操作した後の成果物のキャプチャ。
  • 関連スキル:../../observability/extracting-logs-with-logcat/SKILL.md — デバイスログの読み取り。
  • 関連スキル:../../transfer/extracting-test-artifacts/SKILL.md — adb pull/adb push/run-as。
  • 関連スキル:../../automation/scripting-adb-for-ci/SKILL.md — bash の慣用表現、再試行、ポート転送。
  • 関連セット:../../../instrumentation/scenarios/launching-activities-with-activityscenario/SKILL.md — インストルメンテーションテスト内からの起動。
  • 関連セット:../../../fundamentals/strategies/applying-testing-strategies/SKILL.md — adb とインストルメンテーションのどちらを使って操作するか。

コメント