FizzBuzzのデモ
FizzBuzz? のデモ
1から100までの数をプリントするプログラムを書け。 ただし3の倍数のときは数の代わりに「Fizz」と、 5の倍数のときは「Buzz」とプリントし、 3と5両方の倍数の場合には「FizzBuzz?」とプリントすること。
さあどうやってテスト駆動しましょうか。
(大事なのは Think -> Red -> Green -> Refactor のサイクルを見せること)
正直に行くと
assertEquals(..., fizzBuzz.print()); // 出力のテストどうやるの…
文字列にしたらどうだろう?
assertEquals(fizzBuzz.print(), "1,2,Fizz,4,Buzz,...");
テストデータがまだ大きい 「77 は Fizz? Buzz?」
一口サイズまでテストを小さくしたい
分割統治しよう
ループと判定を分ける。プリントと判定を分ける。
(1..100).map {|n| fizzbuzz(n) }.join(',')
みたいなイメージ。判定なら小さくテストしやすい
ここまで小さくすればテストリストが書ける
[] 3の倍数の時は Fizz と返す [] 5の倍数の時は Buzz と返す [] 3と5の倍数の時は FizzBuzz と返す [] その他の数のときはその数を返す
最初にテストに書く TODO を決める
(やらせ臭くなく「その他の数のときはその数を返す」を選ばないと三角測量できないので注意)
Fizz,Buzz,FizzBuzz は「ただし、」の後の特記事項なので、「その他の数」が一番の正常系というロジックで押す
最初のテスト
「その他の数」でテストを書き始める
テストコードを書く際の議論をここで行う
- テスト名はどうする (Test 前置か否か)
- テストコードの書き順 (assert first)
- プロダクトコードの場所 (影響力が強いので最初から別ファイルに)
- テストデータを選ぶ (1,2,4,...)
仮実装
最初のテストを書いて Red を見せる
リファクタリングをふまえて、最初はベタ気味の名前で
assertEquals("4", FizzBuzz.fizzbuzz(4));
とか
仮実装で Green
(和田) 仮実装の説明を入れる
三角測量
仮実装では実装にならないのでもうひとつデータを選ぶ
assert を増やすか、テストメソッドを増やすかという議論
両者のメリット、デメリット
(和田が説明入れるかも)
できればテストメソッドを増やす路線で
三角測量のテストを書いて Red
きちんと実装して Green
「その他の数のときはその数を返す」に DONE マークを付ける
(和田)TDD の歩幅の説明を入れる
ここまでが「ローギアの TDD 」
(Q&A をやるか?)
次のテストを選ぶ
「3の倍数の時は Fizz と返す」を選択
残り時間次第で仮実装コースに行くか明白な実装コースに行くかを判断
- 時間が無い場合は、明白な実装コースで
- 時間があるなら、 Fizz は三角測量、Buzz は明白な実装の方が説明がスムーズ
「3の倍数の時は Fizz と返す」のテストを書く
仮実装 & 三角測量を使って解く 三角測量のところで剰余を使う
「5の倍数の時は Fizz と返す」のテストを書く
剰余が使えることが分かるので、明白な実装で解く
(和田)明白な実装の説明
リファクタリング
ナビゲータがドライバーを止め、リファクタリングを促す 改善できる / いらいらする ところはないか?
- 引数の名前
- メソッド名
- テストコードの重複
- テストメソッド名
上記を Green to Green でリファクタリングする
(和田) リファクタリングの説明
テストコードのリファクタリング
実装のテストになってしまっているテスト名から仕様を示すテスト名への変更
Q&A
(和田) コミットのタイミングの説明とか
おそらくここまでで時間を使い切る
Keyword(s):
References: