2012年3月20日火曜日

[Scala]BddでFizzBuzz[BDD]

BDDという言葉を初めて知りました。

TDDと違って「振る舞い」を意識してテストを書く!! って言われても、あんまり実感がわかない。

実感わかないけど、まあ手を動かしていきます。

Step1.テストを書く

テストのリストを以下に。

import jp.numa.fizzbuzz.FizzBuzz

class FizzBuzzTest extends Spec with ShouldMatchers {
  describe("only Multiples of 3 ") {
    it("should return Fizz ") {
      val multiple3 = List(3, 6, 9, 12, 18, 21, 24, 27)
      val fizz = new FizzBuzz
      for (num <- multiple3) {
        fizz.getFizzBuzz(num) should be("Fizz")
      }
    }
  }

  describe("only Multiples of 5") {
    it("should return Buzz") {
      val multiple5 = List(5, 10, 20, 25, 35, 40, 50)
      val buzz = new FizzBuzz
      for (num <- multiple5) {
        buzz.getFizzBuzz(num) should be("Buzz")
      }
    }
  }

  describe("only Common Multiple of 3 and 5") {
    it("should return FizzBuzz") {
      val cmultiple3x5 = List(15, 30, 45, 60, 75, 90, 105, 120)
      val fizzbuzz = new FizzBuzz
      for (num <- cmultiple3x5) {
        fizzbuzz.getFizzBuzz(num) should be("FizzBuzz")
      }
    }
  }

  describe("only other number") {
    it("should return number to string") {
      val numbers = List(1, 2, 4, 7, 8)
      val other = new FizzBuzz
      for (num <- numbers) {
        other.getFizzBuzz(num) should be(num.toString())
      }
    }
  }
}


FizzBuzz問題と言うことで、

  • Fizzのみ
  • Buzzのみ
  • FizzBuzzのみ
  • 普通の数字のみ

をそれぞれ得るテストを書く。当然、元のコードは書かれていないのでEclipse使っているとコードは真っ赤っ赤。

Step2.コンパイルできるようにする
FizzBuzz#getFizzBuzzはStringを返すメソッドなので、とりあえず hoge を返すメソッドを定義する

package jp.numa.fizzbuzz

class FizzBuzz {
  def getFizzBuzz(number: Int) = "hoge"
}


Step3.失敗を確認する
EclipseでScalaTestを使うのがちょっと面倒くさかった。

  • Run -&gt;RunConfigulation -&gt; Scala Application -&gt; New -&gt;
  • [Main] -&gt; Project : "FizzBuzz" , Main class : "org.scalatest.tools.Runner"
  • [Arguments] -&gt; Program arugments : -s jp.numa08.fizzbuzz.test.FizzBuzzTest

として、Run 一度設定すれば、項目を埋める必用はなくなるけど、Runconfigulation -&gt; Run からでないと、実行できない?

Step4.実装をする

さて、実装。パターンマッチを使ってチョコチョコっと書いていきます。

package jp.numa.fizzbuzz

class FizzBuzz {
  def getFizzBuzz(number: Int) = {
    number match {
      case num if (num % 3 == 0 && num % 5 == 0) => "FizzBuzz"
      case num if (num % 3 == 0) => "Fizz"
      case num if (num % 5 == 0) => "Buzz"
      case num => num.toString()
    }
  }
}


Steo5.通るまでテスト
実は、テストのコードをミスっていてテストが通らないで困っていたりもしましたけど・・・

Steo6.動くものを作る
Mainオブジェクトを作りました。

package jp.numa.fizzbuzz

object Main {

  def main(args: Array[String]): Unit = {
    val fizzbuzz = new FizzBuzz
    for (num <- 1 to 100) {
      print(fizzbuzz.getFizzBuzz(num) + "\n")
    }
  }

}


さて、完成ですかね。

格好つけて再帰とか使いたいなぁみたいなことはちょっと考えていたら、@kmizuに”再帰は最後の手段”って言われたので見送り(決して方法を思いつかなかったわけでは無い。)

まあ、間違えることは無いだろうけど確認のために anarch golf Fizz Buzz で確認をしておきました。と言っても、フォームからの投稿がなんか上手くいかないので、実行結果をコピペして、diffコマンドで比較したわけですが。

しばらく、Scalaで頑張ります。

0 件のコメント:

コメントを投稿