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

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

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

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

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

##プロジェクトの作成とセットアップ
その２でやったようにプロジェクトのセットアップをします。
ただ、今回はテストコードとソースコードは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」を返す**です。

```rb: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](https://qiita-image-store.s3.amazonaws.com/0/46625/ec63b35c-0b9d-8490-856e-cfa8591648d0.png)

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

![ruby19.png](https://qiita-image-store.s3.amazonaws.com/0/46625/3fbab0b4-9885-6499-32a3-f4b9263c447a.png)

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

```rb:FizzBuzz.rb
class FizzBuzz
end
```

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

![ruby20.png](https://qiita-image-store.s3.amazonaws.com/0/46625/c9096aaa-582f-77c7-5607-613f981d4bcc.png)

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

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

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

![ruby21.png](https://qiita-image-store.s3.amazonaws.com/0/46625/6e3fe0e0-8163-b42e-9bf6-0a2c0a0dfb8f.png)


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

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

…安直とか言うな！

![ruby22.png](https://qiita-image-store.s3.amazonaws.com/0/46625/b51213c4-67ea-cb13-2f55-262a341e28a6.png)

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

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

##テストコードの作成　2歩目
ここからはもうちょっとさくさく行きます。
**「1」を与えたら「1」を返す**ですが、**「2」を与えたら「2」を返す**でもあります。
ということでこれを書きます。
ちょっと長くなるので、付け足す分だけ書きます。

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

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

![ruby23.png](https://qiita-image-store.s3.amazonaws.com/0/46625/60a2fa90-c4e7-1fdc-0378-35044cbc9cdf.png)

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

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

![ruby24.png](https://qiita-image-store.s3.amazonaws.com/0/46625/b7677a05-3e9d-58fa-1926-03735ddfde4f.png)

今度はさすがに一発！

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

```rb: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](https://qiita-image-store.s3.amazonaws.com/0/46625/ef993815-2eef-8894-83c4-67e03f36502e.png)

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

```rb:FizzBuzz.rb
class FizzBuzz
  def fizzbuzz(num)
    if num % 3 == 0 then "Fizz"
    else num.to_s
    end
  end
end
```
![ruby26.png](https://qiita-image-store.s3.amazonaws.com/0/46625/8cecae32-9ca8-4d00-c72d-bdde1f59cfcf.png)

テストもばっちり。

##テストコードの作成　すっとばして最後
そんな感じで次に5の倍数、15の倍数、とやって、最終的に通ったものがこれです。

```rb: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
```

```rb: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](https://qiita-image-store.s3.amazonaws.com/0/46625/f0cad5ad-eda2-e96e-acd0-c8e13fe87643.png)

ゆっくり進めたのでかなり長かったですねー。
でもこれで完成です。
これを使って次の小ネタを考えてますが。それはまた次の機会に。
***
本当はいろいろ調べた出典を書いておきたかったのですが、もうどこから何の情報取ってきたのかわからない状態になっていますorz
情報元の皆様に心から感謝してます。
私も情報出す側にならねばー。