AppiumでAndroid・iOSアプリのテスト実行動画をエビデンスとして残してみよう

https://cdn-ak.f.st-hatena.com/images/fotolife/g/go_dev/20240418/20240418124254.jpg

Software Engineer in Testチーム(通称:SET)でスマホアプリの自動化をすすめている笠間です。現在、SETチームでは、スマホアプリの自動化をすすめています。

現在は、AndroidiOSともにAppium を使い、アプリの肝となるシナリオ30〜40件をターゲットにしており、その作成コストや運用コストを確認しながら、その範囲を広げていこうとしています。

輝く未来を抱きしめて。Software Engineer in Testチーム(通称:SET)で技術支援を行っている daipresents です。

自動化されたエンドツーエンドのテスト(E2Eテスト)を運用していると、そのテストを実行し、失敗したときの原因究明にかかる運用コストは馬鹿にできません。

なぜなら、テストの自動化によって、大量のテストを何回も自動実行できるようになると、その結果を確認するコストも同時に大きくなるからです。

そのために、テストや環境を安定化したり(実はこれが自動化にとって一番大切な仕事かもしれない)、失敗したときの原因究明スピードを速くしたりと、各現場で改善されているのだと思います。

この記事では、失敗したテストの原因究明として一番使いやすい「テスト実行時に動画撮影する方法」を、Appiumを使って実現したいと思います。なお、解説に使う言語は Ruby を利用していますが、Appiumが対応している各種言語で実装されています。

start_recording_screen / stop_recording_screen

Appium には start_recording_screen / stop_recording_screen というメソッドが用意されています。Macで動かしてみたところ、メソッドを利用するには brew install ffmpeg が必要みたいです。動作確認は Android は Emulator、 iOS は Simulatorでしています。

Ruby の例だと以下のように解説されています。

# 録画開始
# Ruby
# ruby_lib example
start_recording_screen
start_recording_screen video_size: '1280x720', time_limit: '180', bit_rate: '5000000' # Android
start_recording_screen video_type: 'h264', time_limit: '260' # iOS

# ruby_lib_core example
@driver.start_recording_screen
@driver.start_recording_screen video_size: '1280x720', time_limit: '180', bit_rate: '5000000' # Android
@driver.start_recording_screen video_type: 'h264', time_limit: '260' # iOS

# 録画終了
# Ruby
# ruby_lib example
stop_recording_screen
stop_recording_screen remote_path: 'https://example.com', user: 'example', pass: 'pass', method: 'POST'

# ruby_lib_core example
@driver.stop_recording_screen
@driver.stop_recording_screen remote_path: 'https://example.com', user: 'example', pass: 'pass', method: 'POST'

とても簡単ですね。

ただ、この例を参考に試したところ、Androidは .mp4 形式で録画できたのですが、 iOS だとうまく録画できませんでした。 video_type: 'h264' だと以下のエラーが出るのです。

Selenium::WebDriver::Error::UnknownError: An unknown server-side error occurred while processing the command. Original error: The screen capture process 'ffmpeg' died unexpectedly. Check server logs for more details
from UnknownError: An unknown server-side error occurred while processing the command. Original error: The screen capture process 'ffmpeg' died unexpectedly. Check server logs for more details

ここをみると video_type: 'libx264' という指定ができるようですが、これも同じエラー。JSON Prameters には以下のように書かれていますがどれもだめ・・・。

options.videoType    string  (iOS Only) The format of the screen capture to be recorded. Available formats "h264", "mp4" or "fmp4". Default is "mp4". Only works for Simulator.

Appiumサーバのログを見ると、どうも、ffmpegを実行するときのパラメタの指定方法が間違ってるかもよ?とメッセージが。だとすればAppium内のパラメタ指定方法が怪しいかもしれない。

困ったので iOS のソースを見てみると、デフォルト値が video_type: 'mjpeg' だったので試してみると、おお! ファイルができた!!! しかし、QuickTimeで開けず、なにか壊れているような・・・。

最後にたどり着いたのがGitHubのこのIssue (Can’t play screen recorded video)。やさしい人が「mpeg4を使えばいけるよ!」と書いていたので試してみたらうまく動きました。さらに iOSは video_fps パラメタによってタイムラプスみたいな動画も作成可能。ファイル容量も圧縮できて便利です。

完成形はこんな感じです。

# iOS
@driver.start_recording_screen video_type: 'mpeg4', video_fps: 5, video_quality: 'low', force_restart: true, time_limit: '300'

# Android
@driver.start_recording_screen video_size: '1280x720', bit_rate: '1000000', force_restart: true, time_limit: '300'

StopするとBase64変換されたデータがかえってくるので、これをそのままファイルにする必要があるのですが、GitHubで調べてみると stop_and_save_recording_screen というメソッドが存在したので、これを活用できます。

@driver.stop_and_save_recording_screen '/Users/dai/sample.mp4'

以上、Appiumを使った動画撮影の解説でした。Emulator や Simulator で動くので(XcodeiOSのバージョンには依存するらしい) 、実機を使わず並列実行するときなどにぴったりです。

さらにこのメソッドを使うと、Android/iOSともに動画撮影できるので、誰でも簡単に失敗原因を特定できます。ぜひご活用ください!