goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について...

74
テスト駆動開発入門(後編) goyoki

Transcript of goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について...

Page 1: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テスト駆動開発入門(後編)

goyoki

Page 2: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

おさらい

1. 最初にテストを書いて実行(RED)

2. テストをパスするまでコードを実装(GREEN)

3. コードをきれいにする(REFACTOR)

これを繰り返しインクリメンタルに実装を進める

RED

GREEN

Refactor

Page 3: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

おさらい

• うるう年判定関数(グレゴリオ暦)

–西暦年が4で割り切れる年は閏年

–ただし、西暦年が100で割り切れる年は平年

–ただし、西暦年が400で割り切れる年は閏年

Page 4: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

今回の概要

• TDDの周辺分野について

–今回は「コードとテストの資産化」をテーマに考え方や方法論を紹介します

Page 5: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

概要

• テストコードの運用

• テストコード運用上の問題

• テストによるコードの資産化

• テストコードのドキュメント化

• レガシーコードでのTDD

Page 6: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

TDDのテストコードの運用

Page 7: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコードの運用

• TDDでのテストの持続的効果–単体テスト容易性の確保

–実装仕様の確保

–自動化された回帰テスト環境の構築

• 継続運用の課題–単体テストとしての整理(前篇)

–運用環境の構築

–テストコードのメンテナンス

Page 8: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

TDDの文脈におけるテストコードの運用フェーズ

• 実装作業中、継続的かつこまめに

–常時実行される回帰テスト

–何度も何度も実行できるように自動化を強力に推進する

Page 9: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

運用環境の構築

• 単体テスト運用環境の軸

• 構成管理システムの運用

• 継続的インテグレーション

–環境の分散

Page 10: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

単体テスト運用環境の軸

クライアント サーバ

手動 JUnit、スクリプト:手動で実行 CIサーバ、ビルドサーバ:手動コマンド

イベント時(コミット前等)

バージョン管理クライアント:コミットに組込IDE:ビルドステップ等に機能

CIサーバ:コミット駆動

自動 スケジューラ:時間駆動 ビルドサーバ:デイリービルド

環境の軸

タイミングの軸

Page 11: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

構成管理システムの運用

• Ex)バージョン管理システム

– コード変更/リリースとテスト実行の同期を取る

–テスト対象の時系列データを確保する

• 単体テストの自動運用の要

–回帰テストによるフィードバックを軽快に得る

Page 12: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

継続的インテグレーション(CI)

• 自動化されたインテグレーションを継続的に実行

1. インテグレーションを統合・自動化• ビルドに単体テストを統合

2. インテグレーションの実行を自動化• インテグレーション用サーバを用意(Hudson有名)

• 統合したインテグレーションを継続的に自動実行する

– コミット時等。ナイトビルドよりもっと頻繁に

– 継続的ですばやいフィードバックを実現

Page 13: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

単体テスト運用環境

作業用PC

構成管理サーバ

DB関連テスト

ストレステスト

規格バリデーション

コミット

更新・自動実行

更新・自動実行

更新・自動実行

制約のあるテストを分散運用することでSlowTest問題や高コストを回避する

Page 14: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

単体テスト運用マトリクス

環境A 環境B 環境C …

テストセット1 ○

テストセット2

テストセット3 ○

テストセット4 ○

テストセット5 ○

….

Page 15: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

実行の分散方針

• TDDのテストは軽快に• 「実行に0.1sもかかる単体テストは、遅い単体テストである」

(レガシーコード改善ガイド)

• Slow Test問題:時間のかかるテストのせいでTDDの効率が落ちる

• 重い/制約のあるテストはサーバ側、自動化へ

– 時間がかかる/特定環境依存/高コスト

• TDDでは必要なテストのみ実行すればよい

–全テスト実行はサーバ側へ

Page 16: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコードの運用まとめ

• TDDのテストの継続的効果

• 単体テスト運用環境の軸

• 構成管理システムと単体テスト

• 継続的インテグレーション

• テスト負荷の分散

Page 17: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコード運用上の問題

Page 18: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコード運用上の問題

• TDDのテストは一般的に継続利用されるため:

– メンテナンスしないと品質悪化

–保守性が悪いとレガシー”テスト”コードとして開発の足を引っ張ってくる

Page 19: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Fragile Test

• 製品コードの変更に弱いテスト

–些細なコード変更で大量のテストが失敗

–仕様や機能とは無関係な変更でテストが失敗

• リファクタリングやCover & Modifyのコストを

増大させる(TDDはリファクタリングを推進するはずなのに・・・)

• TDDでのエントロピー問題

Page 20: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Fragile Test

void test_1() {Hoge hoge = new Hoge(…);

… }void test_2() {

Hoge hoge = new Hoge(…);… }

void test_3() {Hoge hoge = new Hoge(…);

… }

….

void test_100() {Hoge hoge = new Hoge(…);

… }

void test_101() {Hoge hoge = new Hoge(…);

… }

void test_102() {Hoge hoge = new Hoge(…);

… }

テストメソッドがHogeクラスに過依存Hogeクラスのコンストラクタが変更されたら大量のテスト失敗が発生

Page 21: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Fragile Test対策

• 3つの方針

– テスト対象への過依存を避ける

– テストの変更可能性に基づいてテストを設計する

– テストの保守性に基づいてテストコードを設計する

Page 22: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストのテスト対象への過依存を避ける

• テストにおけるテスト対象への4つの過依存

– Interfaceへの過依存

– Behaviorへの過依存

– Dataへの過依存

– Contextへの過依存

Page 23: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストのテスト対象への過依存を避ける

• テストフェーズへの過依存

• Ex)Four Phase Test

– Setup

– Exercise

– Verify

– Teardown

Exersice、Verifyはまだしも、SetupやTeardownで過剰に依存していないか

Page 24: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストのテスト対象への過依存を避ける

• 対策:過剰な依存部を取り除く

–重複するテスト対象呼び出しはないか?→重複を関数やクラスでまとめる

–テスト対象の内部に過剰に依存していないか(リフレクション、Mockなどで無理に内部にアクセスしていないか)

→上位テストで内包できる下位テストは簡略化→問題があればモジュール設計を再検討する

–一部の過依存がまわりを巻き込んでいないか→依存部をラッピングする

Page 25: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

対策例:Creation Method

public void testHoge_first() {Piyo piyo = new Piyo(1, 2, 3);...

}public void testHoge_second() {

Piyo piyo = new Piyo(4, 5, 6);...

}

Page 26: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Creation Method

public void testHoge_first() {Piyo piyo = createUniquePiyo();...

}public void testHoge_second() {

Piyo piyo = createUniquePiyo();...

}

public Piyo createUniquePiyo() {return new Piyo(generateValue(), generateValue(), generateValue());

}

「Customer」という製品コードのへの依存部が削減された

Page 27: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストの変更可能性に基づいてテストを設計する

• 単体テスト設計のアプローチ

–仕様ベース

• 仕様分析によって、仕様保障を目的とするテストを設計する

–構造ベース

• 構造分析によって、構造を網羅するようにテストを設計する

–経験ベース(統計ベース)

• エラー推測、経験を元にテストを設計する

• 過去の欠陥統計などに基づいてテストを設計する

Page 28: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

単体テスト設計のアプローチの扱い

• 仕様ベースのテスト設計を重視不足を構造ベースのテスト設計で補う

–構造はリファクタリングで変化する

• 構造への過依存はFragile Testとなり制約 に

–構造ベースで網羅的に設計したテストはナマモノ

Page 29: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

アプローチの扱い

int hoge(int input)

{

return input * 2;

}

Int型は仕様か、構造的な制約か

Page 30: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

構造の変更可能性

• 構造ベースでも変更可能性に程度がある

–大規模な構造

–仕様としての構造

構造の変更可能性大 小

暫定実装 内部メンバ

ライブラリモジュール等のインタフェース

規格化された構造

Page 31: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

構造の変更可能性

• 構造の変更可能性の2軸– 時間軸方向の変更可能性

– 構造軸方向の変更可能性

Page 32: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

構造軸方向の変更可能性

• 構造的に変更されにくいものか?– 変更可能性:大

• 暫定実装、内部メンバなど

• 保守性(移植性など)が务悪な構造

– 中期• クラス、モジュールなど大まかなレベルの構造

• 保守性が作りこまれた構造

– 長期• 規格として定義される構造、厳格管理された構造

Page 33: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

時間軸方向の変更可能性

• 時間が経過しても変更されにくいものか?– 短期(一時的)

• 暫定使用、実装過程での仮実装など

• 仕様が不定

– 中期• 機能、各部モジュールなど

– 長期• 公的規格、標準規格、根幹的なアーキテクチャなど

Page 34: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

変更可能性への対応

• 時間的・構造的に安定するものから網羅性を高める

– Ex)規格仕様は作りこんでV&V手段として使えるようにする

• 「SQLiteのテストコードは4567万8000行。本体のコードは6万7000行」

–不安的なコードに対するテストコードも不安定暫定実装に対するテストコードも暫定実装

Page 35: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

アーキテクチャ設計による変更可能性の管理

• アーキテクチャ設計段階で変更可能性を大きく制御できる

–外部仕様定義

• 不定な外部要因を局所化・分離する

• テスト容易性を阻害するDOCを局所化する

–内部設計

• 保守性を作りこむ

• モジュール設計により、仕様としての構造を定義する

Page 36: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコード運用上の問題

• Fragile Test

• 変更可能性への対応

• TDDとアーキテクチャ設計

Page 37: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストによるコードの資産化

Page 38: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

TDDによる実装アプローチの変化

• TDDで書かれたコードは全体にわたって

–単体テストが確保される

–単体テスト容易性が確保される

• 自動化された回帰テスト環境がCover & Modifyのアプローチを実現する

Page 39: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify

• 手順

– 1 パスする回帰テストを確保する

– 2 テストが成功する状態を保ちつつ、コードを変更する

Page 40: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Edit & Pray

• 「変更して動かしてみる」

• Cover & Modifyの対比となる実装アプローチ世の中で一般的

• 手順

– 1 コードを変更する

– 2 うまく動くように祈る

Page 41: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify

• 「テストで保護(Cover)して修正(Modify)する」

• テストで修正・変更の影響範囲を絞り込む

– コードの変更作業が安全に

–保守開発で推奨される実装アプローチ

Page 42: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify[実演]

• Case 4 で1234を返す

Page 43: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify例

• リファクタリング

– 1 機能を保護するテストを確保する

– 2 テストがパスする状態を維持しながら、コードを変更する

Page 44: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify例

• TDDによる機能変更

– 1 変更対象の回帰テストを書く

– 2 TDDのサイクルへ

• 変更機能のテストを書く(Red)

• 実装する(Green)

Page 45: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Cover & Modify[課題]

• うるう年判定(前回の課題)

–テストを削除してください

• 追加仕様:

–負の値が入力された場合はfalseを返す

Page 46: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

TDDとCover & Modify

• TDDとCover & Modifyは親和性が高い

– コードをテストに対して最適化されるため、コードのテスト容易性が高まる

• テストで保護しやすくなる

–テストコードが確保される

–そもそもCover & ModifyがTDDのようなもの

Page 47: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

コードの資産化

• TDDはコード資産化効果を促進する

– TDDによりCover & Modifyを実現

• コードの保守性が大きく改善

• コードの資産化が促進される

• 「テストのないコードはレガシーコード」

• 資産化効果はドキュメント・プロセスでなく、コードそのものに宿る

Page 48: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

コードの資産化まとめ

• Edit & Pray

• Cover & Modify

– リファクタリング

–機能追加

• TDDのコード資産化効果

Page 49: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコードのドキュメント化

Page 50: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコードのドキュメント化

• 「テストコード=実装仕様」という設計アプローチ

– TDDでのテスト設計で目指される理想の1つ• Not All!

• 他の理想と共存する

– テストコードを動く実装仕様書として活用する

– バグ出し・品質保証ではなく、仕様記述という目的でテスト設計を行う

Page 51: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Example Driven Development

• EDD。用例駆動開発。TDDの1種

• EDDでのテスト=テスト対象の用例

• テストファーストが苦手な人のためのプラクティスとして有効

• 手順:

–最初に実装コードの用例を考える

–用例をテストで表現する

–以後はTDDのサイクルへ

Page 52: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Example Driven Development[課題]

• 演算器

–整数を入力できる

–入力した整数の計算結果を出力できる

Page 53: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Behavior Driven Development

• BDD。ビヘイビア駆動開発。TDDの亜種

• BDDのテスト=テスト対象のふるまい仕様

– “Behavior Verification”とは異なる

• 手順

–実装のふるまいを考えるそしてふるまいをテストで表現する

–以後はTDDのサイクルへ

Page 54: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

BDDフレームワーク

• 単体テストフレームワークの一種

• xUnitの設計に基づくものが多いが、命名や構造がBDDの思想に合わされている

• 仕様記述のためのDSLを提供するものもある

Page 55: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

BDDフレームワーク

• JUnit

– assertEquals("hoge name", hoge.getName());

– assertEquals(16, hoge.getAge());

• JDave(BDDフレームワーク)

– specify(hoge.getName(), must.equal("hoge name"));

– specify(hoge.getAge(), must.equal(16));

Page 56: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Behavior Driven Development[課題]

• 演算器

–整数を入力できる

–入力した整数の計算結果を出力できる

Page 57: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

ドキュメントとしてのテストコード

• Characterization test

• Test All-at-Onceによるフィーチャ分析

Page 58: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Characterization test(仕様化テスト)

• コードのふるまいや用例を、パスするテストとして表現する

–仕様表現、コードの理解が目的

–満たすべき仕様として回帰テストとして作用する

Page 59: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Characterization test(仕様化テスト)

• Characterization testによるコード解析

– 1 適宜の入出力で解析対象のテストを書く(最初は失敗させる)

– 2 テストがパスするまで入出力の値を調整する

• テスト失敗したら期待値を実行値に置き換える

• 例外が発生したら例外テストに置き換える

–目的が達成されるまでこれを繰り返し、テストを継ぎ足していく

Page 60: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Characterization Test[課題]

• 前回の課題のCharacterization Testを用意する

Page 61: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Test All-at-Onceによるフィーチャ分析

• 実装対象に求められるフィーチャをテストメソッドとしてすべて洗い出す

–テストメソッドはスケルトン。かつignore設定

– TDDの中で1つ1つignore指定除去&スケルトン実装をすすめ、最終的にTDDのテストコードがすべてのスケルトンを内包するようにする

–最終的に、洗い出したスケルトンセットが整合性の取れたフィーチャリストとなる

Page 62: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

Test All-at-Onceによるフィーチャ分析[実演]

• うるう年判定関数で実施

Page 63: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

テストコードのドキュメント化まとめ

• TDDとテストコードのドキュメント化

• EDD/BDD

• Characterlization Test

• Test All-at-Onceによるフィーチャ分析

Page 64: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

レガシーコードでのTDD

Page 65: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

レガシーコードでのTDD

• 単体テスト容易性が低いコードではTDD実行前にコードの修正が必要

–修正では一般的にコードを悪い方に崩すテストの恩恵とのバランスを考慮する必要がある

• Cover & Modifyから外れた修正

• コードを汚くしてしまう修正

Page 66: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

通常のTDD

1. テストを書く

2. テストをパスするコードを書く

3. リファクタリングする

Page 67: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

レガシーコードでのTDD

1. (よく考える)

2. 依存性を排除する

1. 変更点を洗い出す

2. テストを書く場所を見つける

3. 依存性を取り除く

3. テストを書く

4. テストをパスするコードを書く

5. リファクタリングする

Page 68: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

依存性の排除

• リスクを許容するとしても、リスクを抑える– 低リスクなツール支援が使えるなら活用

– 低リスクな変更手段があるなら活用• private→protected

• finalを削除する

– 上位のテストで補完

• リスクにある変更は慎重に考える– “よく考える”

– スクラッチリファクタリングなどでイメージを固める

Page 69: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

スクラッチリファクタリング

• テストや制約を一切無視して自由にリファクタリングする

–テストは記述しない

– リファクタリング結果は使い捨て

–バージョン管理推奨

• 目指している結果が妥当かどうか評価するリスクのある修正を行うときに有効

Page 70: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

依存性の排除例(コンストラクタのパラメータ化)

public Hoge {private MissileCtrl missileCtrl;public Hoge() {

missileCtrl = new MissileCtrl ():}

public void piyo() {…. missileCtrl.発射();….

missileCtrl.発射2();….

}….

}

Page 71: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

依存性の排除(コンストラクタのパラメータ化)

public Hoge {private MissileCtrl missileCtrl;public Hoge(MissileCtrl missileCtrl) {

this.missileCtrl = missileCtrl;}

public Hoge() {thils(new MissaileCtlr());

}

public void piyo() {missileCtrl.発射();

}….

}

Hoge(new FakeMissileCtrl());

Page 72: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

レガシーコードでのTDD[課題]

• 前回課題のBookList改変版

Page 73: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

レガシーコードでのTDDまとめ

• レガシーコードでのTDDのステップ

• 依存性の排除

– コンストラクタのパラメータ化

• スクラッチリファクタリング

Page 74: goyokiinfog.0ch.biz/download/jissen_tdd_2_goyoki.pdf•TDDの周辺分野について –今回は「コードとテストの資産化」をテーマに考え 方や方法論を紹介します

最後のまとめ

• 今回とりあえず覚えてもらいたい要点

–継続的インテグレーション

– Fragile Test

– Cover & Modify

–テストによるコードの資産家

–テストコード=ドキュメントとするテスト設計アプローチ

–レガシーコードでのTDD