specsを読む

Scala用のBDDフレームワーク specs について調べたメモ。APIが読みづらいので、あえてAPIを明記するテストコードも書いてみました。

テスト駆動開発はもう定着していると思うのですが、振舞駆動開発(BDD)の方はやってみたことがなかったので、Scala勉強会@東北の場を借りてやってみました。
scala-tohokuは既に15回もやってます、おそるべし週1ペース。次回で今年最後なので、遊びにきてくださいね。

specsはgoogle codeにホストされていて、QuickStartUserGuideを読めば、だいたい使えると思います。

BDDはざっくり言えば、「仕様書=動くテストコード」を目指しているものだと思います。TDDに比べて、書き方も出力も、より口語に近い文書にしていく感じ。

 import org.specs._

 object someSpec extends Specification("何かの仕様") {

  "何かは" should {
    "真であること" >> {
      "some" must_==/ "SOME"
      "other" must beEqualToIgnoringCase("Other")
    }
  }
 }

と書けば、

 > scalac -cp specs.jar someSpec.scala
 > scala -cp specs.jar someSpec

  Specification "何かの仕様"
   何かは should
   + 真であること

  Total for specification "何かの仕様":
  Finished in 0 second, 27 ms
  1 example, 2 expectations, 0 failure, 0 error

などと、テスト仕様書というよりは詳細設計書をイメージして書いてテストする(この例だとあんまり違いわからないけど)。

BDDの活用についてはさておいて、scalaの慣習でちょっと困るのが、implicit conversion(暗黙の変換)を多用してDSL化することが多いので、文法的には一見きれいに見えますが、きもい!(scaladocsとの対応が読みづらい)

そこで、implicit conversionさせないで、よりJavaっぽくに書いてみました。一回こんな感じで書いたらAPIを追いやすくなりました。

 /*
 * ImplicitConvertionしないでAPIを明記したコード
 */
 import org.specs._
 import org.specs.matcher._
 import org.specs.specification._

 object nonImplicitSomeSpec extends Specification {

  //org.specs.specification.SpecificationStructure
  val futsuu:SpecificationStructure = declare("nonImplicitSomeSpec");
  //org.specs.specification.Sus
  val futsuuSus:Sus = futsuu.specify("implicitしないテスト")

  futsuuSus.should {
   //org.specs.specification.Example
   val kimokunai:Example = forExample("コードがきもくないこと")
   kimokunai.in(
    {
     //org.specs.specification.Expectable
     val str:StringExpectable[String] = theString("some")
     str.must_==/("SOME")

     //org.specs.specification.Expectation
     val expect:Expectation[String] = new Expectation("other")
     // Specification < Matchers < StringMatchers
     val required:Matcher[String] = beEqualToIgnoringCase("Other")
     expect.must( required )

     // 他に AnyMatchers, NumericMatchers, XmlMatchers など、
     // Matcher[T] を生成するメソッドが定義されている。
     // org.specs.matcher.Matchers を参照
    }
   )
  }// end of futsuuSus should
 }// end of NonImplicitSomeSpec


本当はこんなところを調べなくても書けるようにするのがDSLなんでしょうけど、「入りにくい」と感じたらこうやって分解してみるとスッキリしますね。「コードがきもくないこと」は振舞じゃないからテストケースとしてはオカシイのでヨロシク。

コメントいっぱい挟んでることを差し置いても、scalaっぽいコードとは一目瞭然で違います。

scalaかこいいYO!


追:

というわけで見てのとおり、テストをかっこよく書けるので、Javaで書いたアプリをscala+specsでテストするのもアリだと思いました。

テストツールとしてScalaを使うってのも、Scalaの使い方として良いような気がする。


同じカテゴリのエントリ
1.Lift再入門 / 8.javascriptからsubmitできない / 7.Ajax Form / 6.Radio、Checkboxについて / 5.行列型の編集FORM / 4.サーバーサイドバリデーションとサーバサイド関数 / 3.ログインFORM - S.param使ったら負け / 2.Snippetメソッドとして許される型 / sbt0.12.xで依存jar抽出タスク / scala2.10+lift2.5+NetBeans7.2 / Scalaで入門関数プログラミング / reactive-webを試してみました / Lift2.2M1のテンプレート機能 / Scala Compiler Plugin / View Bound/Context Bound / ScalaZa01参加してきました / Akka Frameworkチュートリアルの次 / Akka Frameworkチュートリアルその2 / Akka Frameworkチュートリアル / LiftでJCaptcha / Url Rewrite Filter / sbt-android-plugin / Android SDK for Scala / 祝Lift2.0リリース / Liftの携帯対応まとめ / Scala2.8への移行 / Lift 2.0-scala280-SNAPSHOT/sbt0.7.1 / Scalaお絵かき環境 - Kojo / Lift+Quartzでバッチ / Scala&Liftを採用した理由 / Liftでdate_select系ヘルパーを作る / LiftでAjax / LiftのSubmitかしこい / lift-mapperのpaginateを使う / snippetをspecする / Lift Mapperを拡張する / LiftのDBをMySQLに / Liftプロジェクト環境を整える / Scala本読み比べてみました / NetBeans6.7&scala / じつはScalaはライトな言語 / Scalaバザ~ル / lift1.0所感 / specsを読む / implicit def / ScalaならNetBeansがサイコー / scala勉強会@東北がスタート / それでも俺はLiftをやるってのか / Scala&Liftセットアップ / ブログリニューアル /
コメント

コメントしてください

closed.