独習 スはSpecのス
角谷さんが関西Ruby会議で講演した「スはSpecのス」の実演をトレースしてTDDとRSpec、Autotestの使い方を学びました。
スライドはこちら
http://www.slideshare.net/kakutani/s-is-for-spec-at-rubykansai25
動画はこちらからみることができます
http://www.nicovideo.jp/watch/sm3003102
で成果物はこちら
lib/game.rb
class Game FrameNumber = 10 def initialize @frame =[] end def roll pins @frame << pins end def score @idx = total = 0 FrameNumber.times do total += score_of_this_frame + bonus @idx += (strike?) ? 1 : 2 end total end private def score_of_this_roll ; @frame[@idx] end def score_of_this_frame ; score_of_this_roll + @frame[@idx + 1] end def strike? ; score_of_this_roll == 10 end def spair? ; score_of_this_frame == 10 end def bonus ; (strike? or spair?) ? @frame[@idx + 2] : 0 end end
spec/bowling_spec.rb
$: << File.dirname(__FILE__) + '/../lib' require 'rubygems' require 'spec' require 'game' describe Game do before do @game = Game.new end describe "全部ガターの場合" do before do 20.times{ gutter! } end it "点数は0点になること" do @game.score.should == 0 end end describe "全部1本倒した場合" do before do 20.times{ @game.roll 1 } end it "点数は20点になること" do @game.score.should == 20 end end describe "ストライクの場合" do before do strike! @game.roll(5);@game.roll(3) 16.times{ gutter! } end it "点数は26点になること" do @game.score.should == 26 end end describe "全部ストライクの場合" do before do 12.times{ strike! } end it "点数は300点になること" do @game.score.should == 300 end end describe "スペアの場合" do before do spair! @game.roll(5);@game.roll(2) 16.times{ gutter! } # |7 3|5 2| # 15| 22| end it "点数は22点になること" do @game.score.should == 22 end end describe "受入れテストケースの場合" do before do [1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6].each do |pins| @game.roll(pins) end end it "点数は133点になること" do @game.score.should == 133 end end private def gutter!; @game.roll(0) end def strike!; @game.roll(10) end def spair!; @game.roll(7); @game.roll(3) end end
やってる途中で気がついたんですが、Autotestではテスト対象コード(game.rb)の方はいちどテストに失敗していないと内容を更新してもテストされないみたい。テストコード(bowling_spec.rb)の方はいつ更新してもテストが実行されました。