will and way

ただの自分用メモを人に伝える形式で書くことでわかりやすくまとめてるはずのブログ

同期系スマホアプリのリリースサイクル・テストについて

この記事はCyberAgent エンジニア Advent Calendar 2015の12日目の記事です。

www.adventar.org

昨日はtoguriさんのVRを追いかけるゼミやってます でした。 360度動画がFacebookで見れるようになったり、コロプラさんが白猫のVR化や株式会社360Channelを設立したりとホットな技術。PlayStationVRもお披露目されましたし、盛り上がってるんですね〜! 明日は@yudpppさんです。

今日の記事では自分が携わっているスマホの同期アバターサービスで
どのようにリリースサイクルを回しているかを紹介したいと思います。

特に

  • リリースサイクルのボトルネックはどこか
  • リリースサイクルと強く結びついているテスト
  • バグなくリリースするために心がけていること
  • iOS/Android両プラットフォームリリースオペレーション

について触れていきます。

同期サービスが故に行っている、iOS/Android両プラットフォームの同時リリースオペレーションのノウハウは稀かもしれませんが、工夫ポイントでもあるので少し詳しく紹介させてください。

アバターサービスの技術スタック

フロント

  • 9割がCocos2d-xで実装
  • テキスト入力、ピッカー、アルバム取得などはネイティブ(Java/Objective-C)

サーバー

  • Node JS, Mongo, Redis

通信は同期系通信(発言、ユーザーの位置情報など)はMQTT、ユーザーのタップドリブンの通信はhttpsで行っており、シリアライズにmsgpackを用いています。
私は職種としてフロントエンドで、C++からUIKitやAndroidSDKにブリッジする部分やネイティブに依存する部分、例えばサードパーティSDK組み込みやPush通知、課金周りを主に開発してきました。

それもあって、Google PlayStoreやiTunes Connectをよく触っていたためリリースフローに各プラットフォームの仕様などを還元することがありました。

リリースフローについて

まずは、リリースフローについて紹介します。

おおまかなリリースフロー

f:id:matsuokah:20151212045055p:plain

↑はチームで実際に使っているガントチャートに近いもので、以下のことを管理しています

  • いつどのバージョンのどの機能がテスト可能になるのか
  • いつどのバージョンを申請するのか
  • いつどのバージョンをリリースするのか
  • 特筆すべきこと(iOSアプリの64bit対応やATS、IPv6対応のデッドなど外部要因であり無視できないもの)

また、このガントに載る機能の情報は要件定義が終了し、開発が進められる状態のものです。
チーム全体のスケジュールがここに集約されているため開発陣はもちろん、マスタデータの管理者やテストチームに共有されており、共通認識を持つことで円滑にテストまで行けるようになっています。

フローを説明すると

  1. staging環境のアプリを準備(タグ切り)
  2. staging環境にて仕様テスト、強制終了箇所が増えてないかのモンキーテスト
  3. Apple Storeにアプリを申請
  4. Google PlayStoreでβ公開
  5. Apple のレビューを待つ
  6. レビューが通ったら両OSのアプリを同時にリリースする

iOSのレビュー提出日を基準にスケジュールを組み立てる

ネイティブアプリはAppleのレビュー期間がボトルネックになります。言い換えれば、リリースが若干ながらアンコントローラブルということです。
それ故に、コントローラブルであるアプリの申請日を基準に逆算してスケジュールを組んでいます。

前回のリリースからいかに短い期間で申請を出せるかが リリースサイクルを早く回す為の重要なポイントとなります。

リリースサイクルを早めるメリット/デメリット

メリット デメリット
・ 新機能を早くみてもらえる
・テスト単位を小さくすることができる
・ バグの修正を早く
・ ユーザーにアプリを再認識してもらえる
・ わずかに離脱するユーザーがいる

圧倒的にメリットの方が大きいです。 特に注目したいのが「テスト単位が小さくすることができる」です。テスト単位、コード差分が小さいということは即ちリグレッションリスクを低くできる」ということなのです。

後は、PDCAが早く回せるのでその分アプリの改善をたくさんできるということになります。

また、ホームに埋もれていてもアップデートのバッジによってアプリを見てもらえるので、視覚的な副産物があります。(効果があるのかはわかりませんが笑)

1回のリリースサイクルは約2週間

Appleのレビューにかかるのは約7日、営業日換算で5日です。
更に申請をするまでに組み込む機能の仕様テスト及び、強制終了が増えてないかのモンキーテストを5日とっています。
(現状ではリグレッションテストが行えていないので今後の課題となっています。)

従って1回のリリースサイクルにかかる時間は最短で2週間になります。

定期的に申請までこぎつけるのはかなり骨が折れるので、Facebookが2週間に1度に必ず行っているiOSアプリの定期リリースは心から尊敬しています。

大きい機能をこのフローにのせるには

当たり前ですが、2週間単位のリリースサイクルとはいえ開発する機能によっては2週間の中に収まらない大きな機能が出てきます。

この場合は、トップダウン的に約1~3ヶ月にマイルストーンをざっくりとおいて、大枠が見えたところで2週間のスキームに落としこむという方法をとっています。 大枠はボトムアップ的に見えて来ますが、大体トップダウンのスケジュールに着地します。

また、このような機能は仕様が膨大である場合が多いです。つまり5日間のテストにも収まりません。

そこでdevelopment環境の仕様テストを行っています。

stagingと何が違うかというと、ガンガン開発中・仕様が盛り切っていないfeatureブランチのアプリだったり、ひとまず開発者が仕様を盛り込み終わったdevelopブランチのアプリだったりします。 サーバーにもテストすべき機能が盛り込まれたアプリをデプロイしてもらっています。

また、テストやデプロイするアプリの管理やテスト依頼などの細かいイテレーションはその機能の担当者がやっています。

development環境でテストすることで、仕様の定義漏れに気づくというメリットがありました。

開発者は意地悪なテストをしません。どうしても自分に都合の良いテストしかできません。なぜなら、その機能をどう使えばいいか知っているからです。

しかし、テスターさんはとりあえず同時タップしたり、SDを抜いたり、サスペンド&レジュームしたり、3G回線エミュレートしたり、電池が少ない状態にしたり、画像が数千枚ある端末でテストしたりします。そうすると、仕様が不明確な部分や、実装が漏れているエラー処理を浮き彫りにさせたり、ストレスがある状況での挙動がおかしい現象を見つけることで潜在バグの先手見つけたりすることができます。 それをstagingに前に済ませることで、差し戻しが激減され、結果的にstagingでの5日間のテストで収まるようになっています。

リリース

同期サービスならではである部分を含め、リリースについて紹介していきます。

まず特殊かもしれないポイントですが、AppStoreとPlayStoreでのリリース日を合わせる形にしています。 上位互換の無い機能がリリース、致命的なバグフィクスや運用上の都合で強制アップデートが必要になる場合、同時の方が都合がいいからです。

特に新機能はリリースと同時にキャンペーンやプロモーションを行うことが多いので、AppStoreとPlayStoreのリリースのラグを減らすことは運用上で必須事項となっています。

また、フロントのコードはCocos2d-xで実装されており、Android/iOS共にほぼ同じソースである以上、片方だけが不具合になるケースは稀なので同時リリースがリリースサイクルの観点からも最短であります。

強制アップデートの基準

  • 致命的なバグフィックス
  • 上位互換のない機能
  • プロモーションで必要になる機能の導入やアライアンスなど、運用上の理由

以上の観点で1つでも引っかかれば強制アップデートをするようにしています。それ以外では絶対に行いません。なぜなら、せっかくアプリを遊びに来ているのにアップデートをしないと遊べないのです。

ユーザーは今、この時、アプリを使いたいのです

Androidのアプリのβ公開

社内ではHockey Appを使っており、productionのアプリはダウンロード可能となっています。また、PlayStoreにアップロードするアプリと使っているKeyStoreが同じならば課金も同様にできます。

従って、わざわざβ公開をしなくても動作確認は可能です。

では、なぜβ公開をするのか。公開ボタンを押してからPlayStoreに反映される時間のラグを防ぎ、不具合が起きるリスクを少なくするためです。

直接製品版に公開 ベータ版から製品版にプロモート
1時間〜2時間 3分~15分

実測した結果、上記のようになりました。

ちなみにiOSは公開をポチってから5分~30分です。この取り組みのおかげでAndroidiOSのアプリ公開の時間差は30分以内に収まっています。

特に新機能はリリースと同時にキャンペーンやプロモーションを行うことが多いので、AppStoreとPlayStoreのリリースのラグを減らすことは運用上で必須事項となっています。

と、先程にも触れたように概ね、iOSAndroid同時リリースをする上でこのβ公開は欠かせません。

リリースオペレーション

具体的なオペレーションは審査が通った後からになります。ざっくりとまとめると

  1. レビュー通過のメールが届く
  2. 営業時間が残り4,5時間あれば当日、少なければ、翌営業日にまわす(障害対応可能時間を増やすため)
  3. iTunes Connectで公開をポチる
  4. Google PlayStoreでβアプリを製品版にプロモートする
  5. AppStore公開される
  6. Google PlayStoreに公開される
  7. 必要であれば強制アップデート
  8. アプリ内お知らせやキャンペーン、ツイッターでの告知などのプロモーションを公開する

という、フローで行っています。

特に5,6は今まで述べてきたように分単位で気をつけています。 そのための仕組として、リリースを検知してHipChatに通知をするにしています。

手で確認するのも面倒ですし、アプリで確認するとキャッシュが聞いていたり、Androidのβ版のテスターアカウントに関してはすでに公開されているので、製品版の公開タイミングはわかりません。

リリース検知の手法としてはGoogle PlayStore, AppStoreの公開日をスクレイピングして、前回と差分があればリリースと見なしています。(DOMが変わったらメンテが必要)

github.com

AppStoreの例となるスクリプトを載せておくので適当に御覧ください。

リリース祝いも兼ねて通知は少しだけ、待ち遠しくなるようにしています。最近はマンネリしてるかもですが。

PlayStore

f:id:matsuokah:20151212124521p:plain

ペリーキターーーーっ!

AppStore

f:id:matsuokah:20151212124525j:plain

波キターーーーっ!

f:id:matsuokah:20151212125003p:plain

この日は13:00に公開ボタンをポチってから Google PlayStoreが10分、AppStoreが26分だったようです。従ってこの日は16分の時間差で済みました。こんな感じで、少しテンションを上げてリリースしてます↑age↑(´∀`∩)↑age↑

まとめ

以上、弊社のとある同期系アバタースマホアプリのリリースサイクルについて触れてみました。

他人のお山である以上、リリースサイクルは完全にフレキシブルにはならないものの、コントローラブルなポイントを見つけて、 リリースサイクルに落としこむという事が肝になると個人的に考えています。

文字ばかりにはなってしまいましたが、最後までお読みいただきありがとうございました。