スはスペックのス〜RSpecによるテスト駆動開発の実演〜 - 角谷信太郎 (1/3)‐ニコニコ動画(9)
スはスペックのス〜RSpecによるテスト駆動開発の実演〜 - 角谷信太郎 (2/3)‐ニコニコ動画(9)
スはスペックのス〜RSpecによるテスト駆動開発の実演〜 - 角谷信太郎 (3/3)‐ニコニコ動画(9)
を見ながらテストしてみた。
スライドはこちら。S is for Spec
感想
凄くいい動画・資料でした。
いやぁ、いい時代だ。
1本目は、TDDについての解説です。
2、3本目はボーリングのスコア算出プログラムの実演です。
1本目で解説した内容をテストを書くという「プロセス」を通して実演しています。
この「プロセス」がいいし、TDDって素晴らしいと思えます。
動画自体は1.5時間くらいあって長いし、
実演部は随時止めながら手動かしたので
全部で2時間ちょっとくらいかかりましたが
見る価値、やる価値は十分ありました。
一応ソース
#spec/game_spec.rb require File.expand_path(File.dirname(__FILE__) + "/../game.rb") #require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') #[1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6] => 133 describe Game, "すべてガターの場合" do before do @game = Game.new 20.times { roll_gutter } end it "スコアは0点" do @game.score.should == 0 end end describe Game, "すべて1ピンの場合" do before do @game = Game.new 20.times { @game.roll(1) } end it "スコアは20点" do @game.score.should == 20 end end describe Game, "ストライクの場合" do before do @game = Game.new roll_strike @game.roll(3) @game.roll(4) 18.times { roll_gutter } end it "スコアは24点" do @game.score.should == 24 end end describe Game, "パーフェクトゲーム場合" do before do @game = Game.new 12.times { roll_strike } end it "スコアは300点" do @game.score.should == 300 end end describe Game, "スペアの場合" do before do @game = Game.new roll_spare @game.roll(4) @game.roll(3) # 21 16.times { roll_gutter } end it "スコアは21点" do @game.score.should == 21 end end #[1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6] => 133 describe Game, "Uncle Bobの受け入れゲームの場合" do before do @game = Game.new [1,4,4,5,6,4,5,5,10,0,1,7,3,6,4,10,2,8,6].each {|pin| @game.roll pin} end it "スコアは133点" do @game.score.should == 133 end end private def roll_gutter @game.roll(0) end def roll_strike @game.roll(10) end def roll_spare @game.roll(5) @game.roll(5) end
#game.rb class Game FRAMES_OF_A_GAEME = 10 def initialize @rolls = [] end def roll(pins) @rolls << pins end def score roll_idx = 0 score = 0 FRAMES_OF_A_GAEME.times do |frame| if strike?(roll_idx) # strike score += strike_bounus(roll_idx) roll_idx += 1 elsif spare?(roll_idx) # spare score += spare_bounus(roll_idx) roll_idx += 2 else score += score_of_frame(roll_idx) roll_idx += 2 end end score end private def strike?(roll_idx) @rolls[roll_idx] == 10 end def spare?(roll_idx) @rolls[roll_idx] + @rolls[roll_idx + 1] == 10 end def score_of_frame(roll_idx) @rolls[roll_idx] + @rolls[roll_idx + 1] end def strike_bounus(roll_idx) 10 + @rolls[roll_idx + 1] + @rolls[roll_idx + 2] end def spare_bounus(roll_idx) 10 + @rolls[roll_idx + 2] end end
10フレーム目が特殊な気がするので
追加で書いてみた。
describe Game, "10フレーム目の1投目がストライクの場合" do before do @game = Game.new 18.times { roll_gutter } roll_strike @game.roll(3) @game.roll(4) # 17 end it "スコアは17点" do @game.score.should == 17 end end describe Game, "10フレーム目の2投目がストライクの場合" do before do @game = Game.new 19.times { roll_gutter } roll_strike @game.roll(4) # 14 end it "スコアは14点" do @game.score.should == 14 end end describe Game, "10フレーム目でスペアの場合" do before do @game = Game.new 18.times { roll_gutter } roll_spare @game.roll(4) # 14 end it "スコアは14点" do @game.score.should == 14 end end
あとで
テスト自体は、もう少しきれいになるので、修正しよう。
autotestについて調べよう。
以下、自分用メモ
1つのゴール
"clean code that works"
動作するきれいなコード
1つのテーマ
"The translation of a feeling into a test is a common theme of TDD."
感情をテストにすることが、TDDのテーマである。
不安だ
何かがおかしい
これでいい
退屈だ
→テストを構造化する
→書くのを止める
2つの主張
設計の技法
開発の進め方
2つのルール
テストに失敗した時だけコードを書く
重複を取り除く
3つのモード
Red
Green
Refactoring
3つの技法
"Fake It"
いんちき
"Triangulate"
三角測量
"Obvious implementation"
ふつうに実装する
4つのモード
Think+3つのモード