LoginSignup
5
5

More than 5 years have passed since last update.

[Ruby]Windowsで環境セットアップからTDD開発サンプルまで その4

Posted at

というわけでやっとTDD開発に入ります。
ここまでにこれだけがっつり環境の確認をしているわけですから、想定外のエラーが出たら基本、新しく作ったものが間違っているはずですね。
心して行きます。

TDD開発でFizzBuzz

根本的なところでFizzBuzzの確認をしておくと、

  • 最初は「1」
  • 1づつ増える
  • 3で割り切れるときは数字の代わりに「Fizz」
  • 5で割り切れるときは数字の代わりに「Buzz」
  • 3でも5でも割り切れる(つまり15の倍数)ときは数字の代わりに「FizzBuzz」

となります。
今回はTDDを使いやすいように、与えた数値にが「数値」か「Fizz」か「Buzz」か「FizzBuzz」を返すようなものを作ります。
それを1から順にループ回してあげれば普通のFizzBuzzですね。

プロジェクトの作成とセットアップ

その2でやったようにプロジェクトのセットアップをします。
ただ、今回はテストコードとソースコードは1から作ります。
前にやってるのでさらっと流します。

  1. プロジェクト用の階層「fizzbuzz」を作る
  2. 階層「fizzbuzz」からコマンドプロンプトでbundle initを実行
  3. 作成された「Gemfile」を書き換える ※前回と同じなので丸コピでもいいかも
  4. 階層「fizzbuzz」からコマンドプロンプトでbundle install --path .bundleを実行
  5. 次のコマンドでエラーが予想されるので、「.bundle\ruby\2.0.0\bin」中に「ruby.exe」と「rubyw.exe」をコピー
  6. 階層「fizzbuzz」からコマンドプロンプトでbundle exec rspec --initを実行

ここまでできたら準備OKです。

テストコードの作成 ちょー長い1歩目

TDDですので、最初に作るのはテストコードです。
ソースコードは後回し。
ということで、階層「fizzbuzz」の下の「spec」の下にテストコード「FizzBuzz_spec.rb」ファイルを作ります。
まず最初の条件は「最初が1」ですから、そのテストコード書きます。
「1」を与えたら「1」を返すです。

FizzBuzz_spec.rb
require 'bundler'
Bundler.require

require_relative '../FizzBuzz'

describe FizzBuzz do
  it "should be 1" do
    expect(FizzBuzz.new.fizzbuzz(1)).to eq "1"
  end
end

書き方はいろいろあるようですが、今後はexpect()~で書いた方がいいよ的なことをどこかで見たので、この記法で。
実行するとエラーになります。

ruby18.png

赤く囲った部分を見ると、「そんなファイル読み込めなかったよ!」的な感じですかね。
そりゃそうです、ソースコードファイル作ってないですから。
では「FizzBuzz.rb」という名前で空っぽのファイルを作ってあげて、また実行。
まだ当然エラーになるはずですね。

ruby19.png

ただ、エラーが微妙に変わりました。
今度はファイルについてのエラーは出なくなり、「FizzBuzzなんてしらないよ!」になりました。
そりゃまあクラス作ってませんもんね。
じゃあ、ということでクラス作ってあげます。

FizzBuzz.rb
class FizzBuzz
end

ほんとにクラスだけ作りました。
これももちろんエラーですね。

ruby20.png

お、でもちょっとテストっぽくなってきたぞ?
とりあえずメソッドがないと言われているようなので、じゃあメソッドを追加。

FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
  end
end

引数もらうけど、何もしない、にしてみました。

ruby21.png

おお、すごいテストっぽい!
1を想定してたのに空っぽだったよ!だそうです。
わかったじゃあ1を返してやろうじゃないか。

FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
    "1"
  end
end

…安直とか言うな!

ruby22.png

少なくとも通ったじゃないか!

というわざとらしくカメの歩みのようなことをやっておりますが、地道に進めるって大事なことだと思うんです。
どこかで同じエラー見たら、「あのときのあれだ!」ってわかりますし。

テストコードの作成 2歩目

ここからはもうちょっとさくさく行きます。
「1」を与えたら「1」を返すですが、「2」を与えたら「2」を返すでもあります。
ということでこれを書きます。
ちょっと長くなるので、付け足す分だけ書きます。

FizzBuzz_spec.rb
+ describe FizzBuzz do
+   it "should be 2" do
+     expect(FizzBuzz.new.fizzbuzz(2)).to eq "2"
+   end
+ end

そうすると先ほどのウルトラ安直ソースコードでは当然NGになります。

ruby23.png

なので、与えられた数字をそのまま返すようにします。
数字のままなので、文字に変換して返してあげます。

FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
    num.to_s
  end
end

ruby24.png

今度はさすがに一発!

テストコードの作成 3歩目

1、2と来ましたから次は3です。
ただ、3の倍数が「Fizz」ですから、ついでに6もテストしちゃいます。
3、6のどちらも「Fizz」を返すことです。

FizzBuzz_spec.rb
+ [3,6].each do |num|
+   describe FizzBuzz do
+     it "should be 'Fizz'" do
+       expect(FizzBuzz.new.fizzbuzz(num)).to eq "Fizz"
+     end
+   end
+ end

そしてNGになっていることを確認します。

ruby25.png

で、3の倍数の「Fizz」を実装します。

FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
    if num % 3 == 0 then "Fizz"
    else num.to_s
    end
  end
end

ruby26.png

テストもばっちり。

テストコードの作成 すっとばして最後

そんな感じで次に5の倍数、15の倍数、とやって、最終的に通ったものがこれです。

FizzBuzz_spec.rb
require 'bundler'
Bundler.require

require_relative '../FizzBuzz'

describe FizzBuzz do
  it "should be 1" do
    expect(FizzBuzz.new.fizzbuzz(1)).to eq "1"
  end
end

describe FizzBuzz do
  it "should be 2" do
    expect(FizzBuzz.new.fizzbuzz(2)).to eq "2"
  end
end

[3,6].each do |num|
  describe FizzBuzz do
    it "should be 'Fizz'" do
      expect(FizzBuzz.new.fizzbuzz(num)).to eq "Fizz"
    end
  end
end

[5,10].each do |num|
  describe FizzBuzz do
    it "should be 'Buzz'" do
      expect(FizzBuzz.new.fizzbuzz(num)).to eq "Buzz"
    end
  end
end

[15,30].each do |num|
  describe FizzBuzz do
    it "should be 'FizzBuzz'" do
      expect(FizzBuzz.new.fizzbuzz(num)).to eq "FizzBuzz"
    end
  end
end
FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
    if num % 15 == 0 then "FizzBuzz"
    elsif num % 5 == 0 then "Buzz"
    elsif num % 3 == 0 then "Fizz"
    else num.to_s
    end
  end
end

ruby27.png

ゆっくり進めたのでかなり長かったですねー。
でもこれで完成です。
これを使って次の小ネタを考えてますが。それはまた次の機会に。


本当はいろいろ調べた出典を書いておきたかったのですが、もうどこから何の情報取ってきたのかわからない状態になっていますorz
情報元の皆様に心から感謝してます。
私も情報出す側にならねばー。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5