新年明けましておめでとうございます。わさびーふです。
今年からプロダクト開発を技術でより良くするために私たちのチームで取り組んでいる Tips や Tools などの紹介をしていきたいと思います。
はじめに
Android アプリ開発界隈では、Web 方面に比べると Visual Regression Testing の話題が少ないように感じています。Web 方面では、数年前から Storybook と reg-viz/reg-suit を組み合わせて UI 変更時の品質担保やレビューの負担軽減などを取り組んでいるようだったので、私たちのチームでは Web/iOS/Android で、お互いに良い仕組みなどをどんどん取り入れて行こうと考えています。
参考: Storybook と reg-suit で気軽にはじめる Visual Regression Testing
この記事の内容としては以下の通りになります。
- Visual Regression Testing とは?
- reg-suit とは?
- Firebase Test Lab と reg-suit を組み合わせ使うには?
- Step1. Instrumentation Test で画面のスクリーンショットを撮る
- Step2. Firebase Test Lab plugin for fastlane を使ってローカルにスクリーンショット画像を取得する
- Step3. CI 上で reg-suit を実行する
Visual Regression Testing とは?
Visual Regression Testing は日本語でいうと視覚的回帰テスト、画像回帰テストなどになると思います。
概念自体は複雑に捉えずに簡単に説明すると、人間が主に UI 関するコードの変更を行った際に 変更前と変更後の2枚の写真をピクセル比較するテスト
で、開発現場では Github で Pull-request が作られたタイミングで自動的にテストを行うことで回帰が発生しているかどうかを確認します。
例えば Android アプリ開発に Visual Regression Testing を行うことで、このような見逃しがちな変更時にもプルリクエストのレビュー時などで簡単に視覚的に気づくことができます。
- 左右のマージンを
24dp
から16dp
に変更した。 - themes.xml の colorPrimary の RGB 値を
#051327
から#040F1F
に変更した。 - TextView に設定している
Hello World!
からHello, World!
strings.xml を変更した。
などなど…
あくまで、ここで説明するものは、変更前と変更後の2枚の写真をピクセル比較するテストです。
「いいねボタンを押して、サーバに正常に通信が行われたかどうか?」「音声・動画が正常に再生されているか」などの機能に回帰が起こっているかどうかを判断するのは難しいと思います。
どういうコンポーネント単位でスクリーンショットを撮るか、どのタイミングで撮れば確認したい状態の画面になっているか、などはこれらの実装の設計次第になります。
また、View のアニメーションや画面間の Transition などはアニメーション中のフレームを全部同じ FPS で撮らない限り難しいです。
reg-suit とは?
Visual Regression Testing のために開発されたツールです。
変更前と変更後の差分を検知して、 かなりわかりやすい形で HTML のレポートを(AWS S3、Google Cloud Storage などに)出力してくれます。 また、 比較に使用する画像自体は自分で用意する必要があります。
reg-suit はただのコマンドラインツールでもあるので、ローカル環境でも動作することができます。
Firebase Test Lab と reg-suit を組み合わせ使うには?
Firebase Test Lab と reg-suit を組み合わせ使うには理由があります。
前述の通り reg-suit 自体には画像自体を生成する機能はないため、ネイティブでは何かしらのライブラリや自前でスクリーンショットを撮る仕組みを用意しなければなりません。Instrumentation Test を実行し、そのテストランナー上でスクリーンショットを撮る必要があります。
エミュレータを実行して、その上で撮ることももちろんできますが、Firebase Test Lab で行うことで、テストケース毎の Logcat の解析や動画も確認、パフォーマンスモニタリングも同時に行うことができます。
※ Web のほうでは Storybook の各ストーリーをスクリーンショット撮るために reg-viz/storycap が提供されています。
Step1. Instrumentation Test で画面のスクリーンショットを撮る
スクリーンショットを撮るためのライブラリはいくつか公開されています。やっていること自体はどれもほとんど同じなので、使いやすいものを使って良いと思います。私たちのチームでは使いやすいように自前で実装していますが、そのうち公開したいと思います。
※実装自体はあんまり難しくはないです。
注意点
- Firebase Test Lab では
/sdcard/screenshots
に保存された画像を全て GCS に保存してくれるので、保存する場合はこの PATH にしましょう。 - Bitmap を扱うので、メモリリークに注意する。
(テスト時の AndroidManifest.xml にだけlargeHeap
を有効にしたり)
(Bitmap#Compress 時にformat=JPEG
,quality=90
にしたり)
Firebase 公式
Firebase の公式ドキュメントでも、この記事のように aar をダウンロードという形で提供しているので、あまり良い気はしませんがシンプルではあります。
※/sdcard/screenshots
に保存されます。
Firebase Test Lab インストゥルメンテーション テストのスクリーンショットを作成する
Google 製
保存時の PATH 指定はできず /sdcard/Pictures
に保存されてたのでやめました。
androidx.test.runner.screenshot
Facebook 製
width の指定などもできて高機能ですが、数ヶ月前に試した時は動作しませんでした。
facebook/screenshot-tests-for-android
jraska/Falcon
スクリーンショットを撮ることにだけに特化しているので一番シンプルな作りで、結局私たちはこれを参考にしました。
https://github.com/jraska/Falcon
Step2. Firebase Test Lab plugin for fastlane を使ってローカルにスクリーンショット画像を取得する
Firebase Test Lab をどうやって動作させるかについては、以前に記事を書いたのでこちらを参考にしてください。
Firebase Test Lab を CI に組み込みませんか
注意点
- type を
instrumentation
を設定する。(必須) - devices は複数指定せずに、1 台からやってみる。
- timeout をテストケース数によるがいったん長めに設定してみる。
- download_dir のローカル保存先を指定する。(必須)
以下は私の環境でのサンプルですが、これを実行することにより、fastlane を実行した端末の .results
にスクリーンショットが保存されていることを確認できます。
Step3. CI 上で reg-suit を実行する
reg-suit では画像の保存先に、 AWS S3 や Google Cloud Storage を指定することができます。
また、Github や Slack への通知機能などへの通知ができます。
この記事では reg-suit の設定を要点を絞って説明しているため、詳しくは以下を確認してください。 参考: https://github.com/reg-viz/reg-suit
まずは reg-suit の設定ファイルを作成
以下を実現するために、init 時にプラグインを 3 つ追加しています。
- git hash 単位で比較する。
- GitHub の Pull-request 時にコメントを追加する。
- HTML レポートの出力先を Google Cloud Storage にする。
GitHub に通知するには reg-suit の GitHub Apps を設定する必要があります。
GitHub Apps: https://github.com/apps/reg-suit
※ json 上のコメントは説明するために敢えて記載しているので消してください。
CI 上で reg-suit run を実行する
以下の設定は CircleCI の YAML ですが、どの CI を使っても同じようなやり方になるかと思います。
私たちのチームでは reg-suit run
を実行する前に ImageMagick を使ったりしていますが、みなさんの環境で必要なければ入れなくても大丈夫です。
※ ローカル環境でも実行できるので、CI 上で実行する前にローカルで reg-suit run
を走らせてみるのが良いと思います。
成功した場合は、以下のようにコメントが追加されます
雑記
今年はブログをそこそこ書いていく所存です。
そして、今年から GitHub Sponsors の申請が承認されたので、何卒何卒… m(⁎⁍̴̆Ɛ⁍̴̆⁎)m
次からはチラ裏くらいの記事をしていきたい、おしまい