- 株式会社サイバーエージェント
- Ameba 統括本部
- 主森 理
エンジニアのパフォーマンスを最大化する開発環境とは?テスト自動化で変わる人の役割
今回のソリューション:【Travis CI】
〜エンジニアにしか出来ないことに集中する環境を作るテスト自動化ツール「Travis CI」の使い方〜
自動テストやCIというテーマは、ソフトウェアエンジニアリングの世界では話題が絶えない。しかし「なぜテストやプロセスを自動化するのか?」という本質を突き詰めなければ、企業文化にまで落としこむことは難しい。
株式会社サイバーエージェントでエンジニアを務める主森 理さんは、プロダクティビティエンジニアリングの考え方をベースに、「人が本来やるべきことを出来る仕組み」を徹底的に作り上げている。その哲学やTravis CIの使い方を聞いた。
最新の技術でサービスを創り上げるエンジニアリング集団
僕は2011年4月にサイバーエージェントに新卒で入社しました。これまでにいくつかの事業の立ち上げに関わってきたのですが、現在はAbema TVに出向しサーバーサイドエンジニアを務めています。
今年の5月までは、エンジニアリーダーとして「ラジ生?」のサービスの開発を行っていました。個人でラジオのパーソナリティを体験できる音声のライブストリーミングサービスです。エンジニアチームの構成としてはiOS3名、Android2名、サーバーサイド2名、フロント1名でした。
弊社の場合は言語なども常に新しいものを取り入れていくので、サーバーサイド言語にはGo言語を使用していました。ただ問題点としては新しい言語だと市場にそれを使えるエンジニアが全然いなくて。Go言語のエンジニア、今も絶賛募集中です(笑)。
メンバーの能力を最大化する、プロダクティビティエンジニアリングとは?
「ラジ生?」のチームではTravis CIを初め、様々なツールを用いて開発工程を自動化しているのですが、これはプロダクティビティエンジニアリングという考え方がベースになっています。効率よく、コミュニケーションロスを無くして開発をしていきましょうという考え方です…
ソフトウェアの開発では手動でテストを回したり、デプロイしたり、といった作業が発生すると思うのですが、毎回それらを手で行うのは本当に非効率的です。
毎回することは決まっているので、機械ができることはできるだけ機械に任せ、人は人ができることをするべきだと思います。エンジニアはエンジニアにしか出来ないことに集中する環境を作るために、自動化ツールを最大限に活用しています。
「言った言わない問題」を未然に防ぐ。プロセス自動化の効果
具体的な開発体制はどのように自動化されているかというと、GitHubを中心にTravis CI、Coveralls、HipChatなどを連携させています。gitのブランチモデルは基本的にGitHub Flowに則っていて、そのフローの重要なポイントに自動化の仕組みを取り入れています。
例えばプルリクを投げたらチャットに通知が飛んできたり、gitのリリース用タグをpushするとTravis CIがバイナリをデプロイしたりという形です。バイナリのデプロイ先はGitHub ReleasesとAmazon S3に多重化していて、GitHubが落ちてもリリースが行えるような体制にしているのもポイントです。
このフローを導入する前は手動でデプロイスクリプトを回して、完了したことを目視で確認してチャットに投稿する、という流れでした。
この場合だと連絡することを忘れてしまうこともあって、「もうステージング環境に上げた?」「あ、すみません、終わっています。チャットに書くの忘れていました」「もっと早く言ってよ!」というやり取りが度々あって(笑)。こういうのって本当にくだらないですよね…。
それまでは人間の目で確認していたことをチャットツールのBotが自動で行うことで、デプロイされた瞬間にちゃんと全員に共有されるので「言い忘れ」による無駄がなくなりました。
Travis CIを中心に、「人がやるべきことをやる」仕組みを作る
開発フローを自動化していく上で、今やTravis CIのようなCIツールは欠かせません。Travis CIやCircle CIなど色々と種類があるのですが、導入当時に唯一iOS/Android双方のビルドに対応していたTravis CIを選択しました。
それ以前はリポジトリ管理にGitHub Enterpriseを使っていたので、内部にJenkinsを立ててJenkins職人をしていました(笑)。GitHubに移行してからは外部のサービスの連携が非常に楽になりましたね。
Travis CIが動作するタイミングはいくつか設定していて、「Pull Requestを投げたとき」「Pull Requestをマージした時」「リリース用タグをpushしたとき」の3つです。どのタイミングでもコードの静的解析とテスト、ビルドは走らせています。
それに加えて、Pull Requestマージのタイミングでは開発環境へも自動でデプロイされます。そこで実機で動作確認をして、最終的にリリース用タグをpushするとGitHub ReleasesとS3にデプロイされる、というのが全体像です。ちなみに静的解析ツールはGo言語用のgo vetとgolintを使っています。
GitHubとTravis CIを連携させるとテストやビルドの結果を表示させることができます。ビルドがコケるとPull Requestに「☓」マークが出るようになっていて。「☓」マークが消えるまではレビューをしない方針にしています。
テストを通らないレベルのものを人間がチェックする意味って無いですよね。機械がやるべき仕事が全部できている状態にあれば、エンジニアが設計や書き方の意識合わせを目的にレビューができるようになります。人のパフォーマンスを最大化できるような環境ができていると思いますね。
新しいツールは積極的に取り入れる組織文化
Travis CIは他にもCrashlyticsやCoverallsと連携させて使っています。Crashlyticsはクラッシュレポート解析ツールなのですが、その中のBetaという機能を利用してリリース前のiOS/Androidアプリケーションを自動的にテスターに配布しています。
Coverallsはテストのカバレッジ計測ツールです。カバレッジは100%を目指すものでもありませんが、サーバーサイドのコードは80%以上をキープしようという気概でやっています。
機能追加でコード量がどんどん増えていくので日に日に難しくなっていきますが(笑)。でもそういった高い目標への意識を常に持つことでテストしやすい設計になるし、コード量を増やしたくないのでコピペすることも減り保守性が格段に上がります。
このように新しいものを積極的に取り入れていますが、意識しているのはしっかりとドキュメントとして記録を残すことです。
導入するツールの中にはマッチせずに全然使えないものもあるのですが、そういったこともドキュメント化すると組織としての資産になります。後で誰かがそのツールを使ってみたいと思った時に参考にできるような資料をできるだけ残すようにしています。
あくまでも「良いサービスを作る」ためのテスト
外に出すプロダクトを開発している以上、テストは絶対に書くべきだと考えています。「良いプロダクト作りました!テストは書いていませんが 」というのは恥ずかしいですよね。
そもそも自分がユーザーだとしたら、テストしていないものはバグが怖くて使えませんし。ソースを公開する場合にも同様で、他のエンジニアに安心して再利用してもらうためにもテストは必要なプロセスだと思います。
ただ、エンジニアの1番のミッションはテストではなく「コードを書いて良いサービスを作ること」です。あくまでもサービスとしてのアウトプットを担保するためのテストなので、機械でできる部分はしっかりと取り入れて自動化・効率化することが重要です。
「餅は餅屋に」という考え方ですね。今後もこのように、エンジニアの能力がしっかりと発揮されるような環境づくりを意識していきたいと思っています。(了)