最近はScalaとお友達ですが、未だに文法やら動きがワケわかりません。俺、この言語向いてないのかなー、なんて思いつつもチマチマと書いています。
そんな状態なので、Scalaっぽくない書き方をして後で気づいたり、間違えてバグらせたりで、気づいたら「死んでる…」となっていることが多いです。
グチャグチャになる前にテストを書こう、後でリファクタリングするときの役にも立つ、と思い立ちました。
思い立ったまでは良かったものの、Scalaのメジャーなテストフレームワークについて何も知りません。JavaでいうJUnitのようなスタンダードがあるととても助かりますが…。
Scalaのテストを調べてみるとScalaTestというのが有名処のようです。ScalaTestでは「テスト」ではなく「スペック」というようです。
私の理解だと「テストのためにプログラムの動作結果の羅列するのはおかしいんよ。振る舞いや期待する仕様を書けばテストになる方が自然なんよー。」というスタイルみたいです。振る舞いを書くところから開発するスタイルをBDD(Behavior Driven Development、Wikipedia ビヘイビア駆動開発の項)と言うそうです。へぇー。
思想は素晴らしいのですが、ScalaTestは従来のJUnitのような「テスト」から、振る舞いを書く「スペック」まで、何でも出来るようにしてしまったせいで、ゴチャゴチャです。初心者には何を使えば良いか判断がつきません。
とりあえず、良くわからないままですけどFlatSpecで書くことにしました。
私のScalaプログラミング環境はIntelliJ IDEA+Scala Pluginですので、これとScalaTestを連携させたいと思います。
といっても何も難しいことは無く、下記のようなFlatSpecのスペッククラスを書いたらProjectのツリー図から右クリックして、Runを選ぶ、ほぼそれだけです。
import org.scalatest.FlatSpec
class HogeSpec extends FlatSpec with Matchers {
val hoge = "hoge"
val fuga = "fuga"
"hoge" should "starts with 'h'" in {
hoge.startsWith("h") should be (true)
}
}
テスト結果はIntelliJ IDEAの結果表示ウインドウに、ツリー状に見やすく配置されます。IntelliJ IDEA+Scala Plugin+ScalaTestのトリオはなかなか素敵です。
スペックを書く方法はわかりましたが、1度に複数のスペックを動作させるにはどうしたら良いのでしょう?
さらに言うと1度に複数のスペックを動作させた結果が、IntelliJ IDEAの結果表示ウインドウにも出て欲しいですが、どう書いたら良いのでしょう??さっぱりわかりません…。
まとめ用のクラスAllSpecから、先ほどのHogeSpecと新たにFugaSpecを1度に動作させるという想定で、思いつく手だてを試してみたいと思います。
まずは素直に、まとめ用のクラスで各クラスのオブジェクトを作りexecute() を呼びました。
import org.scalatest.FlatSpec
class HogeSpec extends FlatSpec with Matchers {
val hoge = "hoge"
"hoge" should "starts with 'h'" in {
hoge.startsWith("h") should be (true)
}
}
class FugaSpec extends FlatSpec with Matchers {
val fuga = "fuga"
"fuga" should "starts with 'f'" in {
fuga.startsWith("f") should be (true)
}
}
class AllSpec extends FlatSpec {
new HogeSpec().execute()
new FugaSpec().execute()
}
HogeSpec: hoge - should starts with 'h' FugaSpec: fuga - should starts with 'f' AllSpec: AllSpec
コンソールへの出力ではまとまって実行されているように見えますが、入れ子になっていないし、IntelliJ IDEAは「NO TEST」という悲しい結果を表示します。ダメですね。
次にHogeSpecとFugaSpecをシングルトンにしてスペックは関数内に入れ、まとめ用のクラスから呼んでみました。
import org.scalatest.FlatSpec
object HogeSpec extends FlatSpec with Matchers {
def hogeTest {
val hoge = "hoge"
"hoge" should "starts with 'h'" in {
hoge.startsWith("h") should be (true)
}
}
}
object FugaSpec extends FlatSpec with Matchers {
def fugaTest {
val fuga = "fuga"
"fuga" should "starts with 'f'" in {
fuga.startsWith("f") should be (true)
}
}
}
class AllSpec extends FlatSpec {
HogeSpec.hogeTest
FugaSpec.fugaTest
}
AllSpec: AllSpec
何も出なくなりました。ダメだこりゃ…。
最後にHogeSpecとFugaSpecをトレイトにして、まとめ用のクラスにMix-in してみました。
import org.scalatest.FlatSpec
trait HogeSpec extends FlatSpec with Matchers {
val hoge = "hoge"
"hoge" should "starts with 'h'" in {
hoge.startsWith("h") should be (true)
}
}
trait FugaSpec extends FlatSpec with Matchers {
val fuga = "fuga"
"fuga" should "starts with 'f'" in {
fuga.startsWith("f") should be (true)
}
}
class AllSpec extends FlatSpec
with HogeSpec
with FugaSpec {
//empty
}
AllSpec: hoge - should starts with 'h' fuga - should starts with 'f' AllSpec
コンソールへの出力ではまとまって実行されていて、IntelliJ IDEAにもテスト項目が認識されています。これはなかなか良さそうです。しかし、
という欠点もあってイマイチです。でも良い方法がわからんす、困ったもんです。
< | 2014 | > | ||||
<< | < | 01 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | - |
合計:
本日:
管理者: Katsuhiro Suzuki(katsuhiro( a t )katsuster.net)
This is Simple Diary 1.0
Copyright(C) Katsuhiro Suzuki 2006-2023.
Powered by PHP 8.2.15.
using GD bundled (2.1.0 compatible)(png support.)