Android/iOSアプリを開発している皆様、こんにちは。技術部の松尾(@Kazu_cocoa)です。テストエンジニアとして、サービスの品質を向上するために様々な活動を行っています。特に最近はモバイルアプリに注力しています。
この記事をご覧になっている皆さんは、モバイルアプリに対する品質をどのようにお考えでしょう?例えば、アプリがクラッシュしないとか、アプリが機能不全無くシナリオを実施できるとか、そういう面は想像が容易だと思います。品質に対する機能的な側面の指標の1つですね。
品質を考える上では機能的な側面だけではなく、非機能的な側面も考える必要があります。例えば、モバイルアプリを使っているときにサクサク動いているとか、そういう観点は利用時の効率性という側面を持ちます。これにはCPU使用率やメモリ使用量、通信量、見せかけのUIなどが関係してきます。これらの指標を常時取得、監視する、ということは(私が聞く限りでは)あまりされていないのではないでしょうか。(組み込み開発であれば、常に確認しているであろうことですが。)
この記事では、私たちが経験した失敗と、その学びのために行い始めたモバイルアプリの資源監視に焦点を当てて話をします。
Androidにおける資源監視の話
失敗の経験
弊社では過去にCPUを使いすぎる問題を埋め込んだAndroidアプリを世にリリースしてしまいました。比較的新しい端末における短時間の利用ではあまり気づかないですが、古い端末にて長時間アプリを利用していると明らかにアプリの動作が緩慢になる類のものでした。
使っているうちにクラッシュするわけではないので、Fabric/Crashlyticsなんかでは即座に気づくこともできませんでした。しかし、弊社に送られてくるご意見やレビューを観察していると『動きが遅くなった』というような書き込み件数が増加している傾向にありました。分析を進めるなかで、CPU使用率などの資源利用量が不具合が発生したバージョンを境に増加していることを知りました。
無事、不具合は修正したのですが、弊社のリリースフローの中でちゃんと資源監視を行っていれば少なからず世に出ることを防げた問題でした。これは、私たちがアプリをリリースするまでに、機能的な要素は毎回確認しつつも、非機能的な要素は時折しか確認できていなかったことが引き起こした問題でもありました。
KPTによるTryの見定め
この問題をKPTの振り返り時にどのように防止できるか考えました。(弊社では、「クックパッドモバイルアプリの開発体制とリリースフロー」にある通り、定期的にKPTとして振り返りを実施しています)
解決したい問題は アプリをリリースするまでに意図しない資源の異常利用を検出するです。理想としては、リリース物そのものに対して、そのような数値を計測し続けることです。(Proguardやlog送信などの設定がリリース物同様であることが重要であるため。)
Android Studio1.3からはCPUの資源監視が容易にできるようになりました。ただ、この機能は開発時やこのような不具合を見つけようと使っている時にデバッグの一部として発見できる可能性は高くなります。しかし、常にリリース物に対して数値を観察できるわけではありません。
資源監視を行う手段として adb
コマンドの sysinfo
を使うことにしました。このコマンドはAndroid2.3などの時代から、システムの情報を取得するために利用していた方も多いかもしれません。(ツールの話は後述)
リリースごとの資源監視
現在のクックパッドのAndroid/iOSのリリースでは、Appiumを使った自動化されたテストを複数シナリオ実施しています。テスト対象としてのアプリは、Androidは特にリリース物をそのまま動かしています。この自動化された仕組みに資源監視を組み込むことで、リリースまでの間に必ず資源監視ができるようになります。これにより、今後はバージョンごとに常に同じシナリオに対して監視が可能なので過去を比較にしながら異常の検出が可能になりました。
人手による実施だと操作に対する時間の点で多少の揺らぎが発生してしまいますが、それの考慮はほとんど必要ありません。自動化された環境だから可能な方法ですね。
資源監視の成果
ここ5ヶ月くらいの間、前述した方法にて資源監視を行い続けていました。その間、意図しない資源喰いがないことを確認しながらリリースを繰り返すことができるようになりました。もちろん、その期間の中で資源喰いの問題が改善してることも確認できました。
資源監視のためのツール
droid-monitor
以下に、資源監視として使っているライブラリを公開しています。
https://github.com/KazuCocoa/droid-monitor
やっていることは非常に簡単で、Rubyスクリプトで adb
コマンドで得た情報を整形し、Googleの提供するグラフ描画のChartsを使いグラフにしているだけです。もちろん、serial指定することで1台の計算機に複数のAndroid端末を接続していても、それぞれの端末に含まれるアプリの資源を計測可能です。実質、構想から動作させるまでに2人日とかかっていないため、費用対効果という意味でも必要十分なものでした。
※Android 6.0対応対応など、まだ欠けているところもあります
droid-monitorによる資源監視例
droid-monitorでは、CPU、memory、network、gfxinfoの4つの情報をサポートしています。このライブラリを実施しながらテストシナリオを実行することで、リリースごとの資源監視として指標を取得しています。
以下ではそのうち幾つかのグラフを例としてのせます。(すべて、GitHubのREADMEに添付しているサンプルです。)
CPU
memory
Android OS 4.2を境に、取得できる形式が変わっています。それの境目は、接続端末のAPIバージョンを読んで自動で識別します。以下画像はAndroid OS4.2のものです。
Net
ネットワークのsend / receiveの双方を、別々のグラフとして出力します。
iOSの資源監視の話
iOSでも同様に探してみましたが、iOSでは adb
ほど気軽に計測する手段がありません。そのため、前述した adb
ほど現実的に計測するスクリプトは作れていません。
Instruments経由で計測はできますが、Appiumを実行する時にinstrumentsも利用するため現状は使うことができません。シミュレータ上でAppiumを実行する時に特定プロセスのCPU使用率など監視できそうですが、現在はそこまで手が行き届いていません。
締め
AndroidアプリやiOSアプリの資源監視は、Webアプリの監視ほど日常的に行われるものではありません。一方で、資源を使いすぎる問題は開発時には意図しないところで湧き出てきたりします。それは利用時の品質を大きく損ねる可能性が高いものです。この記事では、弊社の実際の失敗とその改善話を交えながら、その問題に対する改善話を載せました。
最後に
サービスの品質にはモバイル/Web問わず、様々なSoftware Qualityに関する知見が必要です。Software Qualityが関わる領域は既に様々な分野の知見を蓄積しています。一方、 サービスの品質として一様な指標はまだまだです。私たちは、今回のような機能的/非機能的、はたまた組織的な側面から、様々な知見を持ってより良い品質のサービスを創造するための志を持った仲間を募集しています。