FizzBuzz 問題をお題に TDD
ここ何日かRubyをぼちぼち勉強中。
- 作者: Yugui
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/06/26
- メディア: 大型本
- 購入: 27人 クリック: 644回
- この商品を含むブログ (253件) を見る
ちょっと飽きたので、FizzBuzz をお題にして TDD してみようと思い立ちやってみた。
前提
- TDD 初心者
- Ruby 初心者
参考
FizzBuzz での TDD については下記を参考にさせてもらった。
FizzBuzz with TDD - Logic Dice
#91 [Python][TDD]テスト駆動開発でFizzBuzzしてみようず! « Python « a wandering wolf
[TDD の練習] FizzBuzz 問題: biac の それさえもおそらくは幸せな日々@nifty
仕様
テストコード
require 'test/unit' require 'fizzbuzz' class TC_FizzBuzz < Test::Unit::TestCase def setup @obj = FizzBuzz.new end def test_multiple_of_3 assert_equal("Fizz", @obj.say(3)) assert_equal("Fizz", @obj.say(18)) end def test_multiple_of_5 assert_equal("Buzz", @obj.say(5)) assert_equal("Buzz", @obj.say(10)) end def test_multiple_of_3and5 assert_equal("FizzBuzz", @obj.say(15)) assert_equal("FizzBuzz", @obj.say(45)) end def test_other_number assert_equal(2, @obj.say(2)) assert_equal(4, @obj.say(4)) assert_equal(7, @obj.say(7)) assert_equal(14, @obj.say(14)) assert_equal(16, @obj.say(16)) end def test_not_decimal assert_raise(ArgumentError, "invalid argument") { @obj.say(1.5) } end def test_zero assert_raise(ArgumentError, "invalid argument") { @obj.say(0) } end def test_minus_number assert_raise(ArgumentError, "invalid argument") { @obj.say(-1) } end def test_string assert_raise(ArgumentError, "invalid argument") { @obj.say("a") } end end
プロダクトコード
class FizzBuzz def say(n) if n.to_s =~ /\D/ || n <= 0 raise ArgumentError, "invalid argument" end if n % 5 == 0 && n % 3 == 0 return 'FizzBuzz' elsif n % 5 == 0 return 'Buzz' elsif n % 3 == 0 return 'Fizz' else return n end end end
疑問
参考にしたサイトは、どれも 引数 n を取るメソッドをもつクラスを作って、そのメソッドに対してテストしている。
仕様としては、"1 から 100 までの数字をコンソールに表示する"ってのがあるので、そのメソッドを引数1から100までループさせる呼び出し側ロジックが必要なんだけど、それをテストコードに含める?それともTDDってメソッド単位を保証するもの?って疑問。
たとえば、こんなやつ↓
require 'fizzbuzz' obj = FizzBuzz.new 1.upto(100) do |i| puts obj.say(i) end
というようなことを、Twitter でつぶやいたら、ありがたい助言をいくつか頂いた。
@gab_km さん、@kyon_mm さん、@biac さん、ありがとうございます!
そこから得た現時点での TDD についての理解。
- コードに不安があるならテストする
- TDD はテスト(開発)手法のひとつ
- 狭義には UnitTest を指すことが多い
- 広義にはいろんなテストレベルに適用することを指す
- 各テストレベルにおける確認の粒度(メソッドとかクラスとかコンポーネントとか)と合わせてテスト実装を行う
今回のお題においては、メインロジックの方は非常に単純なので、メソッドさえ動作保証できれば一回動かして確認すればいいかなと判断。
テストコードには含めないことにした。
でも、実際にこれをテストコードに含めるとしたら、どういうケースにするのかな?
戻り値では確認できないし、コンソール出力をファイルに落として確認とか?これもあとで調べよう。
最近行われた TDD カンファレンスの TL とか見てると、TDD を既に実践されてる方にとっては何周か回った話なんだと思うし、色々な考え方があるらしいことも知ってる。
まだちゃんと消化できてない部分もあるので、Ruby の文法をある程度やったらテスト駆動開発入門の写経をしながら自分としての理解を深めるつもり。
- 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2003/09
- メディア: 単行本
- 購入: 45人 クリック: 1,058回
- この商品を含むブログ (161件) を見る