Hatena::Grouprubyist

うんたらかんたらRuby RSSフィード

2010-04-10スはスペックのス~RSpecによるテスト駆動開発の実演

スはスペックのス~RSpecによるテスト駆動開発の実演

| スはスペックのス~RSpecによるテスト駆動開発の実演 - うんたらかんたらRuby を含むブックマーク はてなブックマーク - スはスペックのス~RSpecによるテスト駆動開発の実演 - うんたらかんたらRuby

スはスペックのス~RSpecによるテスト駆動開発の実演~ - 角谷信太郎 (1/3)‐ニコニコ動画(9)

スはスペックのス~RSpecによるテスト駆動開発の実演~ - 角谷信太郎 (2/3)‐ニコニコ動画(9)

スはスペックのス~RSpecによるテスト駆動開発の実演~ - 角谷信太郎 (3/3)‐ニコニコ動画(9)

を見ながらテストしてみた。

スライドはこちら。S is for Spec


追記

RE: スはスペックのス~RSpecによるテスト駆動開発の実演 - うんたらかんたらRuby - Rubyist


追記その2

autospecの結果をgrowlで通知 - うんたらかんたらRuby - Rubyist


感想

凄くいい動画・資料でした。

いやぁ、いい時代だ。


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つのモード