# アジャイルサムライ 第Ⅴ部 アジャイルなプログラミング ## 第12章 ユニットテスト:動くことがわかる ### 12.1 ラスベガスへようこそ ブラックジャック・シミュレーターに、誤ってジョーカーを追加してしまうバグが発生した。 原因は夏のインターン生が、ジョーカーの有無の認識の相違を知らないまま埋め込んでしまっていた。 このようなことを二度と起こさないためには…ユニットテストが必要である。 ### 12.2 はじめてのユニットテスト **ユニットテスト**は、**メソッドレベルの粒度**で書く小さいテストである。 変更を行うたびに書き、変更の結果が期待通りであるかを明らかにする。 テストコードは、最終的に製品として残るプロダクトコードには含めない。 危なっかしい所を全てテストする。(エクストリーム・プログラミングのマントラ) テストの自動化が難しい場合も、あきらめずに自動化を試みる。それでも無理な部分は手動のテストでカバーする。 #### ユニットテストのメリット * 素早いフィードバックが得られる。 * 極めて低コストでリグレッションテスト(変更による影響を確かめるテスト)を実行できる。 * デバッグ時間を大幅に削減できる。 * 自身をもってデプロイできる。 ## 第13章 リファクタリング:技術的負債の返済 ### 13.1 どうしてこうなった 競合他社の追い上げを受ける中、すぐさま対応を開始したが、コードの保守性に難があった。 コピー&ペーストした部分が多すぎて、1か所修正しようとしても膨大な数の修正が必要となったり、 スピード重視で仕上げた乱雑なコードが扱いづらかったりした。 このような「技術的負債」が積みあがると、保守性が著しく低下し、修正期日・コストともに膨大になってしまう。 ### 13.2 技術的負債 **技術的負債**とは、手抜きコードや乱雑な変数名、重複したコード等、期日に間に合わせることと引き換えに犠牲となった「コードの質」のことである。 これらは放置すると時間と共に積み上がっていき、気づくと手に負えないほど保守性が低下する。 そもそも新規開発を行う限り、技術的負債が無いことはまず無い。 コードを書くのが複雑で辛い作業になってきたときに、初めて多重債務を背負っていることに気づく。 これらの負債は少しずつ返済していくことが大切である。これがリファクタリングの作業である。 ### 13.3 リファクタリングで技術的負債を返済する **リファクタリング**は、全体の振る舞いを変えることなく、少しずつ継続的に変えていくことである。 これらの細かい技術的負債の返済を継続的に行えば、開発速度は加速する。毎週…いや毎日…いや毎分ごとにでも良い。極力間隔を開けずにリファクタリングを行うのが良い。 リファクタリングの具体例 * **名前の変更**:変数名・メソッド名等、コード上で定義した名前を修正する。**命名規約**をあらかじめ作っておくと良い。また、誰が見ても推測できるよう、意図は明確に。 * **機能の抽出**:Mainメソッドに直接処理を書くのではなく、別にメソッドやクラス、コンポーネント等の**モジュールを定義**しておき、それらを呼び出すようにする。 * **コメントを書く**:各処理ごとにコメントアウトし、何をしているのかを分かりやすくする。但し、行数が多くなるため、処理が重くならない程度に。 * **変数のインライン化**:余計な変数宣言を無くし、一行に詰め込んでしまう。 #### 大がかりなリファクタリング リファクタリングが1週間かかりそうな大がかりなものの場合、1つのユーザーストーリーとしてリファクタリングを扱う。 やるべきか悩んだら…プロジェクトの終了は近いか。近いならやる意味はない。遠ければ少しずつやれないかを検討する。 ## 第14章 テスト駆動開発(TDD) ### 14.1 テストを先に書く **テスト駆動開発(TDD)** はごく短いサイクルを繰り返しながら、ソフトウェア設計を行う技法である。 以下の3つを繰り返す。 1. **Red(テスト失敗)**:テストの失敗パターンをまず書く。新しいコードの意図をテストで示す。 2. **Green(テスト成功)**:失敗パターンを成功させられるよう、コードを書いていく。技術的負債はこの時点では考えなくてよい。 3. **リファクタリング**:Greenになったら、変更箇所のリファクタリングを行う。**変更部分の質を即座に修正することで、短い間隔でのリファクタリングができる。** #### TDD成功のためのルール 1. **失敗するテストを1つ書くまでは、コードを変更してはならない。** 2. **「危なっかしい所」を全てテストする。** **→確実に動くために必要なコードのみを書けるようになる!** #### バグを修正する前に失敗するテストを書く意義(TDDのRed状態の意義) * バグの本質を理解したと示せる。 * 自信をもってバグ修正に取り掛かれる。 * バグが二度と現れないことを保証できる。 ### 14.2 テストを使って複雑さに立ち向かう #### TDDのメリット * 先にテストを書くことで、複雑なコード設計にも立ち向かえる。 * 設計に自信が持てる。 * 同時にたくさんのことを考えなくて済む。 * 問題の粒度を細かくし、最善の解決策を得られる。 * コードベースの保守・修正を容易にする。 ## 第15章 継続的インテグレーション(CI) ### 15.1 デプロイでありがちな失敗 * ヒューマンエラー、タイプミス、バグ→言わずもがな。テストで取る。 * チームメンバーとの連絡ミス * 動作エラー、設定ファイルの誤り→良く起こりがち * 開発環境とデプロイ環境の違い→良く起こりがち * 古くなったドキュメント こうした失敗を無くし、常に本番環境へのデプロイに慣れておけるのが、自動化による継続的インテグレーションである。 ### 15.2 リリースに備える文化 「プロジェクトの本番は初日から始まっている。」1日目から本番環境にあるかのように扱うこと。 本番環境で扱う際の作業をしなければならない。 そこでアジャイルサムライはリリースに備えることを好む。 * 開発されている時間よりも、利用されている時間の方が長い。 * リリース可能なシステムへの変更に慣れていける。 →継続的インテグレーション ### 15.3 継続的インテグレーションとは 継続的インテグレーションとは、開発者がソフトウェアに加えた変更を取り込んで、全体として統合する作業を継続的に続けていく取り組みのことである。 コードのマージ(統合)の期間が空くほど難しくなる。 また、ビルドの時間は長すぎると支障をきたす。10分以内にとどめる。 ### 15.4 どうすればうまくいくのか * ソースコードリポジトリ:Github等のリポジトリにコードを集約する。 * チェックイン手順:Githubのブランチ機能を使うとより良い。 1. 最新のコードをpull 2. 変更を加える。 3. テストを行う。 4. 最新のコードpull 5. 再度テストを行う。 6. チェックイン(push) * ビルドの自動化:ビルドエージェントを用いて、自動化されたビルドを行い、エラーがあればチームに知らせてくれる。自動ビルドから自動デプロイに繋げる。 * 作業単位を小さくする。:リファクタリング等と同様に、細かい間隔で。 ###### tags: `読書`