ここしばらく公開できる勉強会の資料がなかったので久方ぶりに社内の開発の様子について書いてみます。
今回はXPのプラクティスにも挙げられている継続的インテグレーションについて。
継続的インテグレーションってなんだろう
一応よくまとめられているページを紹介しておきます。
■ 継続的インテグレーション - オブジェクト倶楽部
要は
- バグは早く見つけるほど修正のコストがかからない
- そのためにソフトウェアのビルドを頻繁に行うのがよい
- ビルドが「成功したビルド」であるか確認するために都度テストを行う
- 頻繁に行えるようにビルドとテストをできる限り自動化する
という取り組みです。
うちの会社で開発に使っているのは主にスクリプト言語なのでコンパイル等は行わないのですが、ファイルをテスト用サーバに配備して動く状態にすることをビルドと同義に考えます。 とにかくアプリケーションを動かせる状態にするのがビルドと言うことで。
ともあれ継続的インテグレーションはアプリケーションの品質を保つためにはかなり有効なプラクティスです。
継続的インテグレーションは英語でContinuous IntegrationなのでCIなどと略して呼ぶ場合もあります。
継続的インテグレーションの実践
FFの社内では実際に以下のようなサイクルで動いてます。
- 毎日深夜にCI環境のアプリケーションの更新(ビルド)
- リポジトリ上のHEADのソースが配備される
- データベースのスキーマも最新のバージョンに
- CI環境での自動テストの実行
- ユニットテストとSeleniuimによるテスト
- 結果をメンバーにメールで通知
- 翌朝の確認
- 問題があれば確認担当が朝会で報告して対処
というわけで1日1回のビルドとテストです。
もっと頻繁に回せればベストなのですが、自動テストのSeleniumの実行にかなりの時間がかかるので1日1回としています。
それでもテストがこけていた場合は前日行った変更が原因と言うところまで絞り込めるので、修正はかなり楽です。
二年余り機能追加を続けているアプリケーションが腐らずに運用できているのも、継続的インテグレーションのおかげです。
継続的インテグレーションの構築の仕方
ビルドの自動化とテストの自動化さえできればCIの構築は簡単です。
自動化さえ出来ていれば、あとはそれをスケジューリングして確認する運用を組み立てるだけです。
逆に言うと自動化が出来ていなければまずその自動化をする必要があります。
ビルドの自動化
FFでは以下の仕組みを駆使してビルドの自動化を実現しています。
- Subversion
- Rake
- マイグレーション
基本的にRakeからsvnコマンドを叩いてファイルを配備し、マイグレーションによってデータベーススキーマを更新します。
これによりPHPアプリでは以下の二つのコマンドを実行するだけでビルド完了です。(初回はこのほかにチェックアウトがいりますが)
$ rake release_all stag=trunk ptag=trunk
$ rake migrate
Railsのマイグレーションが激しく便利なのでPHPでも簡単なマイグレーションの仕組みを作って使っています。
Railsアプリでは同じく二つのコマンドでビルドが完了します。(同じく初回は要チェックアウト)
$ svn up
$ rake db:migrate
自動化は割と真面目にやろうとするとしんどいことも多く、中途半端なところまででお茶を濁したくなることもありますが、徹底的にやったほうが後々幸せになれます。 規模が大きくなるほど手間もかかりますが、見返りも大きいです。
テストの自動化
テストの自動化は以下の二本の柱で行っています。
- ユニットテスト
- Selenium
これら自動テストの作成に関しては機能追加や修正が続く間は並行して継続的に行っていく必要があります。
開発の際のお約束として習慣化するのがよいです。
ある機能に関して作成や変更を行った場合は、セットでテストの作成や変更も行います。
たくさんの機能を一気に作って、あとでまとめてテストを作るとか考えるとたいていうまくいきません。
運用
自動化ができていれば、あとはそれらを組み合わせて運用を組むだけです。
- ビルドの定期的な実行
- テストの定期的な実行
- 結果の通知と確認
- 「成功したビルド」が得られなかった場合の対処
これに関してはLinuxサーバ側のCronでビルドとユニットテストを行い、WindowsテストマシンのタスクスケジューラでSeleniumを実行するようにしています。
そして結果はメンバーにメールで送られてきますので、それを確認します。
何かテストが失敗していたら「成功したビルド」が得られなかったということで、それを得るために優先的に失敗した部分の修正作業を行います。
ちなみに確認まできちんと運用に組み込まないと、何日もテストが失敗していたのに気がつかなかったなんてこともあります。
成功しないビルドでは意味がありませんので、運用を考える際にはそこまで考慮に入れる必要があります。
まとめ
以上、ウェブアプリケーションの開発で継続的インテグレーションやってるよと言う話でした。
運用の構築にはそれなりに手間がかかりますが、回りだしてしまえば運用コストは高くないので、構築にかけたコストは確実にペイできると思います。 (アプリケーションが小規模すぎるものだと見合わないかもしれませんが)
またビルドとテストの自動化はリリース作業と確認の簡略化にも役立ちますので頻繁なリリースの助けにもなっています。