目次
第1章 チーム開発とは
1.1 1人だけでも開発はできる
1.2 チーム開発で直面する課題
1.3 どのように課題に立ち向かうか
1.4 本書の構成
- 第2章:ケーススタディ
- 第3~5章:基礎的なプラクティス
- 第6~7章:継続的デリバリーとリグレッションテスト
1.5 本書を読む前の注意点
- 最適なプラクティスはケースバイケース
- どのツールを使うかに正解はない
第2章 チーム開発で起きる問題
- 2.1 ケーススタディの前提
プロジェクトの前提条件
2.2 ケーススタディ(1日目)
- 問題1:重要なメールが多すぎて優先順位を決められない
- 問題2:検証用環境がない
- 問題3:別名フォルダでブランチを管理している
- 問題4:データベースの再作成が困難
2.3 ケーススタディ(1日目)における問題点
- 問題1:重要なメールが多すぎて優先順位を決められない
- メールの件数が多いために重要なメールが埋もれてしまう
- ステータス管理ができない
- 一覧性,検索性が弱い
- メールでプロジェクトを管理することの課題
- 問題2:検証用環境がない
- 問題3:別名フォルダでブランチを管理する
- 問題4:データベースの再作成が困難
2.4 ケーススタディ(2日目)
- 問題5:起動するまで壊れていることに気づかない
- 問題6:他メンバーの修正を上書きして消してしまう
- 問題7:自信を持ってリファクタリングできない
- 問題8:バグの修正時期がわからず,デグレードも追跡できない
- 問題9:ブランチ・タグを活用できていない
- 問題10:テスト環境や本番環境では動かない
- 問題11:リリースが複雑で手順書が必要となる
2.5 ケーススタディ(2日目)における問題点
- 問題5:起動するまで壊れていることに気づかない
- 問題6:他メンバーの修正を上書きして消してしまう
- 問題7:自信を持ってリファクタリングできない
- 問題8:バグの修正時期がわからず,デグレードも追跡できない
- 問題9:ブランチ・タグを活用できていない
- 問題10:テスト環境や本番環境では動かない
- 問題11:リリースが複雑で手順書が必要となる
2.6 理想的なプロジェクトとは
- チケット管理システムに課題などが集約されている
- できる限りバージョン管理システムを利用する
- 繰り返し再検証可能なCIシステムを用意する
- 環境の影響を最小限にとどめ,常にリリース可能にしておく
- すべてを記録して追跡可能にする
2.7 本章のまとめ
第3章 バージョン管理
3.1 バージョン管理システム
- バージョン管理システムとは
- バージョン管理システムを使うとなぜ便利なのか
- 変更内容という最も基本的な記録が残る
- バージョン間の差分を簡単に確認できる
- 間違って他人の変更を上書きしないで済むしくみがある
- ロックモデルとマージモデル
- 任意の時点まで巻き戻すことができる
- ファイルベースとチェンジセットベース
- 複数の派生を作ることができる,ある時点での断面を保存できる
3.2 バージョン管理システムの移り変わり
- バージョン管理システムがない時代(1970年代以前)
- RCSの時代(1980年代)
- CVSの登場(1990年代)
- VSS,Perforceなど商用ツールの登場(1990年代)
- Subversionの登場(2000年代)
- 分散バージョン管理システムの登場(2005年以降)
- 番外編:GitHubの登場
- バージョン管理システムの導入状況
3.3 分散バージョン管理システム
- 分散バージョン管理システムを使うべき5つの理由
- リポジトリの完全なコピーをローカルマシンに持つことができる
- 動作が速い
- 一時的な作業の履歴管理が容易である
- ブランチ,マージが手軽にできる
- 場所を選ばないコラボレーションが可能
- 分散バージョン管理システムのデメリット
- 真の意味では最新バージョンはシステム上存在しない
- 真の意味ではリビジョン番号はない
- ワークフローが柔軟に設定でき過ぎるため混乱しやすい
- 考え方に慣れるのに時間がかかる
3.4 バージョン管理システムをどう使うべきか
- 前提
- バージョン管理システムで管理すべきもの
- ソースコード
- 要件書,設計書などのドキュメント
- データベーススキーマ・データ
- 設定ファイル
- ライブラリなど依存関係定義
3.5 Gitを使ったスムーズな並行開発
- ブランチの使い方
- ブランチとは
- リリースブランチとは
- クローンとブランチの作成
- コミットとコミットログ
- ブランチの切り替え
- バグ修正後のコミット
- masterへのマージ
- masterへのPush
- ブランチの使い方のまとめ
- タグの使い方
- タグとは
- タグの作成
- タグの確認
- タグの取得
- タグ名とブランチ名を同一にするのを避ける
- タグの使い方のまとめ
- Detached HEADとは
3.6 Gitを使った開発フロー
- Gitを使ったワークフローのパターン
- 中央集権型ワークフロー
- GitHub型ワークフロー
- ブランチ戦略のパターン
- git-flow
- github-flow
- 筆者の事例(折衷案)
- 最適なフローとブランチ戦略は現場によって異なる
3.7 データベーススキーマとデータの管理
- データベーススキーマを管理する必要がある理由
- データベース管理者の変更管理を任せた場合
- 共有データベースでスキーマを変更する場合
- データベーススキーマをどのように管理すればよいか
- バージョン管理に必要な要件
- データベースマイグレーションとは
- データベースマイグレーションの機能
- データベースマイグレーションツール
- Migration(Ruby on Rails)
- south(Django)
- Migrations Plugin(CakePHP)
- Evolution(Play Framework)
- 具体的な使い方(Evolution)
- 規約
- SQLファイルの適用
- 開発者間でのスキーマの同期
- 不整合の管理
- データベースマイグレーションの注意点
3.8 設定ファイルの管理
3.9 依存関係の管理
- 依存関係解決システム
- JVM系言語
- スクリプト系言語
- 依存関係を管理するメリット
3.10 本章のまとめ
第4章 チケット管理
4.1 チケット管理システム
- プロジェクトがうまく回らない理由
- 紙やメール,Excelでタスク管理をすることの問題点
- チケット管理システムの導入メリット
- タスク管理をするための基本機能がある
- 一覧性,検索性が高い
- 情報の一元管理と共有が可能である
- レポーティングに利用できる
- 他システムとの連携が可能,拡張性がある
- チケット駆動開発とは
- チケット駆動開発の具体的手順
- チケット駆動開発を徹底する場合
4.2 主なチケット管理システム
- OSS製品
- Trac
- Redmine
- Bugzilla
- Mantis
- 商用製品
- JIRA
- YouTRACK
- Pivotal Tracker
- Backlog
- GitHub
- ツール選定のポイント
- チケット管理システムの応用事例
4.3 チケット管理システムとバージョン管理システムの連携
- 連携によって実現する機能
- コミットからチケットへのリンク
- チケットからコミットへのリンク
- コミットと同時にチケットのステータスを変更する
- 連携の設定方法
- GitHub
- GitHubのissue
- Service Hooks
- GitHubとPivotal Trackerの連携
- GitHubとJIRAとの連携
- Trac/Redmine
- Backlog
- BacklogのGitとの連携
- BacklogとGitHubの連携
- Git自身の用意するHookを使う方法
4.4 新機能の開発,バグの修正時のワークフロー
- ワークフロー
- ①チケットの起票
- ②担当者のアサイン
- ③開発
- ④コミット
- ⑤リポジトリにプッシュ
4.5 「あのバグいつ直ったの」という問い合わせに答える
- Pivotal Trackerの例
- 記憶に残っている文字列で検索
- 検索
- チケットからソースコードの変更を探す
- Backlogの例
- 検索
4.6 「なぜこんな変更が入ったんだろう」という疑問を解決する
4.7 本章のまとめ
- チケット管理とバグ管理,要求管理について
第5章 CI(継続的インテグレーション)
5.1 CI(継続的インテグレーション)
- CI(継続的インテグレーション)とは
- インテグレーション
- インテグレーションを継続的に行うのがCI
- 開発をアジャイル化する
- ウォーターフォール開発の開発フェーズ
- アジャイル開発の開発フェーズ
- なぜCIのようなプラクティスが求められるか
- コストメリット
- 市場の変化のスピード
- スピードと品質を両立させるには
- CIに必要なもの
- バージョン管理システム
- ビルドツール
- テストコード
- CIツール
- テストを書くためのフレームワーク
- テスト駆動開発(TDD)系フレームワーク
- 振る舞い駆動開発(BDD)系フレームワーク
- 主なCIツール
- Jenkins
- TravisCI
5.2 ビルドツールの使い方
- 新規にプロジェクトを始める場合
- プロジェクトのひな型作成
- 依存関係の定義
- テストの実行
- Eclipseへのインポート
- 既存プロジェクトを自動ビルド可能にする場合
- ビルドツールのまとめ
5.3 テストコードの書き方
- CIの対象となるテストの種類
- テストをいつ書くのか
- 新規にプロジェクトを始める場合
- 既存プロジェクトにテストがない場合
- バグ修正または新機能を追加した場合
- 厄介なテストをどう書くか
- 外部とのやりとりがあるテスト
- モッキングフレームワークを使ってテストする
- インメモリデータベースを使ってテストする
- データベース変更管理や設定ファイル管理のテスト
- UIを伴うテスト
- 厄介なテストは工数とのトレードオフ
5.4 Jenkinsを使ったCIの実行
- Jenkinsのセットアップ
- ネイティブパッケージを使ったセットアップ
- Jenkinsで何ができるのか
- ジョブの新規作成
- ソースコードをチェックアウトする
- 自動でビルドおよびテストを実行する
- 定期実行
- バージョン管理システムをポーリング
- バージョン管理システムからプッシュする
- ビルドの記述
- 結果を集計してレポーティング
- カバレッジを計測する
- JUnitXML形式でレポートを出力するのが効率的
- カバレッジ計測ツール
- Maven Coberturaプラグインのインストール
- Java系ライブラリの探し方
- Jenkinsプラグインの設定
- 静的解析をする
- 通知の設定をする
5.5 CIの運用
- ビルドが壊れたらどうするか
- Subversionなど中央集権型バージョン管理システムの場合
- Gitなど分散バージョン管理システムの場合
- ビルドを壊したときの罰ゲーム
- テストしてからマージする
- トレーサビリティの担保
- ビルドとコミットを関連づける
- チケット管理と連携する
5.6 本章のまとめ ―― CIによって得られるもの ――
第6章 デプロイの自動化(継続的デリバリー)
6.1 デプロイとはどうあるべきか
- デプロイの自動化における恩恵
- 細かくたくさんリリースできればリスクをコントロールしやすくなる
- フィードバックを早く得られるようになる
- 組織がスケールする
6.2 デプロイの自動化
- デプロイの自動化における共通認識
- デプロイメントパイプライン
- 自動化によりデプロイの速度を加速させる
- 誰でもデプロイが行えるようにすることが重要
- プロビジョニングツールチェーン
6.3 ブートストラッピング(Bootstrapping)
- Kickstart
- Kickstartの利用方法
- 利用する際の注意点
- Kickstartの設定例
- Vagrant
- 開発者ごとに実機を用意することは難しい
- 仮想環境を利用する際の懸念点
- Vagrantとは
- Vagrantのインストールと実行方法
6.4 コンフィグレーション(Configuration)
- 自動化を行わない場合の問題点
- Chef
- Chefの構成
- ディレクトリ構成とファイル配置
- node.json
- setup.json
- solo.rb
- default.rb
- virtualhost.conf.erb
- Chefの実行方法と実行結果
- Chefを利用するメリット
- Chefを利用する際の注意点
- Chefを利用するタイミング
- serverspec
- serverspecとは
- serverspecのインストール
- テストファイルの記述方法
- httpd_spec.rb
- git_spec.rb
- serverspecの実行方法と実行結果
- serverspecのメリット
- ベストプラクティス(その1)
- Vagrantfile
- default.rb
- ベストプラクティス(その2)
- 物理サーバがサービス投入可能になるまでの流れを自動化する例
- リリース作業についてのアンチパターン
6.5 オーケストレーション(Orchestration)
- Capistrano
- Capistranoのシステム構成
- Capistranoのインストール
- deploy.rb
- Capistranoの実行方法
- Fabric
- Fabric(直列実行)の場合
- Capistrano(並列実行)の場合
- ローカルサーバとリモートサーバの操作の違いを理解する
- Fabricの実行方法
- Jenkins
- マスタノードとスレーブノードの連携
- スレーブノードの追加
- ジョブの追加
- ジョブの実行
- ベストプラクティス
- JenkinsとFabricを組み合わせる
- セキュリティについて考慮する
- 手作業でデプロイするケース
6.6 運用について考慮する
- サービスを止めないデプロイ方法
- ブルーグリーンデプロイメント
- クラウド時代のブルーグリーンデプロイメント
- ロールバックについての考察
- 退路は常に用意する
- データベーススキーマのバージョン管理
- ロールバックの検証
- ソース更新のみのリリース時のロールバック
- データベーススキーマ更新時のロールバック
6.7 本章のまとめ
- PaaSを利用する手段
第7章 リグレッションテスト
7.1 リグレッションテスト
- リグレッションテストとは
- テスト種別の整理
- チームを支援する技術面のテスト(第1象限)
- チームを支援するビジネス面のテスト(第2象限)
- 製品を批評するビジネス面のテスト(第3象限)
- 技術面のテストを使った製品の批評(第4象限)
- リグレッションテストの必要性
- デグレードの発生
- テストを自動化すべき理由
- リグレッションテストの自動化で目指すこと
7.2 Selenium
- Seleniumとは
- Seleniumの利点
- 自動化テストケース作成が簡単
- 多くのブラウザやOSをサポート
- Seleniumコンポーネント
- Selenium IDE
- Selenium Remote Control(Selenium RC)
- Selenium WebDriver
- テストケースの作成と実行
- Selenium IDEのインストールと実行
- Seleniumのテストケース
- 良いテストケースとは
- Selenium Serverを使ったテスト実行
- Seleniumの実践活用
- 画面が変更されていないかをテストする
- Seleniumテストを安定させるためには
7.3 JenkinsとSeleniumの連携
- JenkinsとSeleniumの連携手順
7.4 Seleniumテストの高速化
- Jenkinsの分散ビルドでテストの並列実行
- Jenkinsの分散ビルドの構成
- 分散ビルドの設定
- Seleniumテスト並列化の難しさ
7.5 複数のアプリケーションバージョンでのテスト
- アプリケーションのデプロイ
- テストケースをバージョン管理システムからチェックアウト
- Seleniumでのテスト