Slide 1

Slide 1 text

アプリに開発者モー ドを用意する 2015-01-15 Potatotips #13 黒川 洋 / @hydrakecat

Slide 2

Slide 2 text

こんなことはないですか ( その1) 開発者「 サー バー に○○ というログが送信されるのを確 認してください」 テスター「 どうやって確認すれば良いのですか?」 開発者「」 開発者「A/B 対象のユー ザー の場合は UI が○○ になって いることを確認してください」 テスター「 どうやったら対象ユー ザー になれますか?」 開発者「」( 新規登録を20 回くらいやれば...)

Slide 3

Slide 3 text

こんなことはないですか ( その2) 社内ユー ザー「 電車の中で使っていたら、 変な挙動が」 開発者「 すみませんすみません。 スクリー ンショットと かありますか?」 社内ユー ザー「 ないです。 再現もできませんでした。」 開発者「」 開発者( 移動中)「 あ、 クラッシュした。」 開発者「 ログ見たいけれど、 手元にマシンがない。 家に 着くまで待つか。」 開発者「」( ログが流れてしまったときの顔)

Slide 4

Slide 4 text

開発者モー ドとは 開発/ テストに特化した機能を有効にした状態。 リリー スビル ドには含まれない。 たとえば、 以下のような操作を可能にす る。 ユー ザーID やトー クンなどの詳細情報の表示 A/B フラグなど本来はユー ザー が変更できない設定の変更 サー バー からのレスポンスの書き換え ログの取得/ 表示

Slide 5

Slide 5 text

例: デバッグオプション 通常時 開発者モー ド時

Slide 6

Slide 6 text

開発者モー ドの必要性 開発時 いちいちリモー トデバッグしたりコー ドを変更して、 サー バー のレスポンスを書き換えなくて済む 通常はユー ザー に見せない情報を表示するので、 デバッグ しやすい テスト時 サー バー 側を変更したり複雑なプロキシの設定をせずにテ ストが可能 ⇒ テストを依頼しやすい ログなどの情報が取れるので、 デバッグが容易

Slide 7

Slide 7 text

開発者モー ドの注意点 開発用のコー ドがプロダクションに入らないようにする 実際のレスポンスとダミー レスポンスが乖離しないように ダミー レスポンスでのテストを信用しすぎない ⇒ mitmproxy といったプロキシも併用する

Slide 8

Slide 8 text

実装方法 (Android Studio) Android Studio の flavor を使うと便利 以下は、testflight という flavor を定義しているところ

Slide 9

Slide 9 text

フラグの切り替え SharedPreferences で管理 サー バー レスポンスを書き換えるようなものは、 後述のダ ミー レスポンスと併用する方が良い

Slide 10

Slide 10 text

詳細情報の表示 ユー ザー ID や、 トー クンなどデバッグに便利な情報 ダイナミックな情報を表示するときの工夫 トー ストの利用 印( マー ク) を付ける

Slide 11

Slide 11 text

ログの表示 Timber を使って、 ロー カルファイルにログを書き込む java.util.logger を使うと、 ログファイルサイズに上限を設け られる メソッド名を出したい場合は、 自分でスタックトレー スか ら取り出す必要がある @Override public void e(Throwable t, String message, Object... args) { final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); final StackTraceElement e = stackTrace[5]; logger.logp(level, e.getClassName(), e.getMethodName(), String.format(message, args), t);

Slide 12

Slide 12 text

ダミー レスポンス Retrofit を使っているなら、Mock Client を使うと楽 API からファイルパスへのマッピングをしておく 例: GET http:///a/b ⇒ a/b/get.json private static class MockClient implements Client { ... @Override public Response execute(Request request) throws IOException { String path = "dummy/platform" + uri.getPath() + "/" + request.getMethod().toLowerCase() + ".json";

Slide 13

Slide 13 text

今後やりたいこと スクリー ンショット + ログファイル + 設定のダンプを一発 で取れるようにする 録画 ログレベルの制御