Movatterモバイル変換


[0]ホーム

URL:


Mitsuyuki.Shiiba

Spockのドキュメントを読んだよ

社内の勉強会でなんかしゃべれーってことになり。なんとなくSpockがどっかで気になってたので、SpockどころかGroovyすら触ったことほぼないですけど、ドキュメントをサラーっと読んで面白いなーと思うところをSpock Web Consoleで動かしつつ紹介してみたりしました!復習がてらもういちど読んでみまする。

SpockBasics

https://code.google.com/p/spock/wiki/SpockBasics

Example

全体はこんな感じかな。読みやすいね。

class MyFirstSpecificationextends Specification {def"pushing an element on the stack"() {    setup:def stack =new Stack()def elem ="push me"    when:      stack.push(elem)    then:      !stack.empty      stack.size() ==1      stack.peek() == elem  }}

これをWebConsoleで実行してみるテスト!

MyFirstSpecification - pushing an element on the stack

失敗するようにしてみると。

      stack.size() ==2

こうなる

MyFirstSpecification - pushing an element on the stack   FAILED   Condition not satisfied:      stack.size() == 2   |     |      |   |     1      false   [push me]      at MyFirstSpecification.pushing an element on the stack(Script1.groovy:12)

キャーステキー!!!

てことで説明を読んでみる。

Blocks

6つのブロックがある。

  • setup:
  • when:
  • then:
  • expected:
  • cleanup:
  • where:
setup:

準備するとこ

setup:def stack =new Stack()def elem ="push me"
when: と then:

when: と then: はセットで使われる。when: でテストしたいことを実行して、then: でチェック。
then: のところはassertion使わなくても、bool値になってればいいみたいね。読み易いや。

when:stack.push(elem)then:!stack.emptystack.size() ==1stack.peek() == elem
例外の場合

thrown()メソッドが使えると。

when:stack.pop()then:thrown(EmptyStackException)stack.empty

例外の内容をチェックしたい場合はこんなふうにできる。

when:stack.pop()then:def e = thrown(EmptyStackException)e.cause ==null

もちょっと違う書き方だとこんな感じ。こっちのが型がはっきりしてるからIDEにやさしいよって。それと、前から読む感じになるので、読みやすいよって。僕もこっちのがなんとなく好きだな。

when:stack.pop()then:EmptyStackException e = thrown()e.cause ==null

例外が投げられなかったことのチェックはこんな感じ

def"HashMap accepts null key"() {  setup:def map =new HashMap()  when:  map.put(null,"elem")  then:  notThrown(NullPointerException)}

モックを使ったテストなんかも書けるよーって。詳細はhttp://docs.spockframework.org/en/latest/interaction_based_testing.html かな。

def"events are published to all subscribers"() {def subscriber1 = Mock(Subscriber)def subscriber2 = Mock(Subscriber)def publisher =new Publisher()  publisher.add(subscriber1)  publisher.add(subscriber2)  when:  publisher.fire("event")  then:1 * subscriber1.receive("event")1 * subscriber2.receive("event")}

publisher.fire("event")を呼び出したら、1回だけsubscriber1.receive("event")が実行されるよってことみたいね。
mockとかspyとかありそうなので、また今度チェックしてみよっと。

expected:

実行してチェックを1行で書いたほうが自然なときはwhen:とthen:じゃなくて、expected:が使えるよーって。例えばこういう場合は

when:def x = Math.max(1,2)then:x ==2

expected:使って一行で書くほうが分かり良いよね

expect:Math.max(1,2) ==2
cleanup:

後処理すね

setup:def file =new File("/some/path")file.createNewFile()// ...cleanup:file.delete()

例外が投げられてもここは実行されるとのこと。いいなー。

where:

パラメタライズドテストで使うっぽいすね。これいいすね。さらっとhttp://docs.spockframework.org/en/latest/data_driven_testing.html を読んでみた。

例えばこういうテストをしたいとき

class MathSpecextends Specification {def"maximum of two numbers"() {        expect:// exercise math method for a few different inputs        Math.max(1,3) ==3        Math.max(7,4) ==7        Math.max(0,0) ==0    }}

こう書けるす。

class Mathextends Specification {def"maximum of two numbers"(int a,int b,int c) {        expect:        Math.max(a, b) == c        where:        a | b | c1 |3 |37 |4 |40 |0 |0    }}

読みやすくて素敵すなー。さらに、メソッドの引数は where:で分かるとのことで書かなくてもよいと。それと入力値と期待値の間はもう一個パイプを増やした方が分かり良いやろーって。こうなる

class DataDrivenextends Specification {def"maximum of two numbers"() {         expect:         Math.max(a, b) == c         where:         a | b || c3 |5 ||57 |0 ||70 |0 ||0     } }

ちょっとのことだけど。そゆとこ気を遣ってるのいいねー。

パラメタライズドテストの実行結果

実行結果がどういう風に出力されるかってのを見たいので、失敗するようにしてみよう。

class DataDrivenextends Specification {def"maximum of two numbers"() {         expect:         Math.max(a, b) == c         where:         a | b || c3 |5 ||57 |0 ||50 |0 ||0     } }

んで、WebConsoleで実行!

DataDriven - maximum of two numbers   FAILED   Condition not satisfied:      Math.max(a, b) == c        |   |  |  |  |        7   7  0  |  5                  false      at DataDriven.maximum of two numbers(Script1.groovy:4)

ふむふむ。ところで @Unroll というアノテーションをつけるとパラメータ毎に展開してくれるっぽい。やってみよう。

class DataDrivenextends Specification {     @Unrolldef"maximum of two numbers"() {         expect:         Math.max(a, b) == c         where:         a | b || c3 |5 ||57 |0 ||50 |0 ||0     } }

結果はこうなった。なる。

DataDriven - maximum of two numbers[0] - maximum of two numbers[1]   FAILED   Condition not satisfied:      Math.max(a, b) == c        |   |  |  |  |        7   7  0  |  5                  false      at DataDriven.maximum of two numbers(Script1.groovy:5) - maximum of two numbers[2]

でも、パラメータの値をメソッド名に展開してくれる仕組みがなかったっけ?と思ってたら次に書いてあったわ。

class DataDrivenextends Specification {     @Unrolldef"maximum of #a and #b is #c"() {         expect:         Math.max(a, b) == c         where:         a | b || c3 |5 ||57 |0 ||50 |0 ||0     } }

実行ー!

DataDriven - maximum of 3 and 5 is 5 - maximum of 7 and 0 is 5   FAILED   Condition not satisfied:      Math.max(a, b) == c        |   |  |  |  |        7   7  0  |  5                  false      at DataDriven.maximum of #a and #b is #c(Script1.groovy:5) - maximum of 0 and 0 is 0

そうそう、これこれ。分かりやすいね。

Specifications as Documentation

ドキュメントとしての仕様か。

setup:"空の銀行口座を用意して"// ...when:"100円振り込むと"// ...then:"残高が100円になる"// ...

てことで

Spockいいねー。

早速 Groovy-Eclipseだっけか?を入れてみたら何かとコンフリクトしてるっぽくて元々入ってたプラグインも出てこなくなったので、また今度やってみるー(ノД`)シクシク

プロフィール
プロフィール画像
株式会社カケハシでソフトウェアエンジニアをやってます。
検索

引用をストックしました

引用するにはまずログインしてください

引用をストックできませんでした。再度お試しください

限定公開記事のため引用できません。

読者です読者をやめる読者になる読者になる

[8]ページ先頭

©2009-2025 Movatter.jp