Spock は素晴らしい!のですが、最大限機能を生かしきれてないと、よく感じるのでメモ。

基本形

package net.bucyou

import spock.lang.Specification

class SampleSpecification extends Specification {

    // すべての feature (テスト) 前に実行される
    def setup() {

    }

    // すべての feature (テスト) 後に実行される
    def cleanup() {

    }

    // 最初の feature (テスト) 前に実行される
    def setupSpec() {
    }

    // 最後の feature (テスト) 後に実行される
    def cleanupSpec() {
    }

    // feature method (テスト)
    def "うどんをたべるとうまい"() {
        given:
        def i = ..
        def udon = ..

        when:
        def result = i.eat(udon);

        then:
        result == "Umai"
    }
}

うどんはうまい。
このとき、result == “Mazui” とかを仮に結果に入れてみると、やたら詳しく比較が出てくれます。
これは、IntelliJ IDEA の機能ではなく、Spock の機能のようです。

スクリーンショット 2013-08-16 17.55.30

Map や List でも、同様に細かい比較を見ることができるので、大助かりであります。

featureの文法

feature は、setup, when, then, expect, cleanup, そして where
6つのブロックによって構成されています。
いつも、Gherkin の影響で given を使っていたのですが、
これは、setup の エイリアスとして定義されているので、動作に問題はありません。

Blocks2Phases

公式のドキュメントによると、流れは上のような感じ。

setup: データの準備とか (1)
when: 実際に何かを実行 (2)
then: 結果の検証 (3)
expect: 何かを実行して検証 (2,3)
cleanup: データのお掃除とか (4)
where: なんか図では、えらいことになってますが後述

then, when など順番を逆に書いたりすると、エラーって落ちたりするっぽいです。
when -> expect -> then というものダメです。
when, then, when, then と複数回書くのは問題ないようです。
then が前のブロックに続けて複数あるときなどは and も使えるようです。

where block

where は複数の入力データを、同じテスト (setup, when, then, cleanup) に通すときに便利なブロックです。

class SampleSpecification extends Specification {

    def "where!!"() {
        setup:
        println "setup"

        when:
        println "when"

        then:
        println "then"
        println "a=" + a
        println "b=" + b

        cleanup:
        println "cleanup"

        where:
        a | b
        1 | "Udon"
        2 | "Soba"
    }
}

これを実行すると、以下の様な結果がやってきます。

setup
when
then
a=1
b=Udon
cleanup
setup
when
then
a=2
b=Soba
cleanup
class SampleSpecification extends Specification {

    def "where!!"() {
        setup:
        println "setup"

        when:
        println "when"

        then:
        println "then"
        println "a=" + a
        println "b=" + b

        cleanup:
        println "cleanup"

        where:
        a | b
        1 | "Udon"
        2 | "Soba"
    }
}

こういう、表形式な書き方もできるので、テストをわかりやすくするためには
なかなかゴキゲンになれる機能ですね!

Mock については、また今度書きます。

apple-touch-icon-144-precomposed

現在、このブログではオリジナルテンプレートとして、bootstrap を利用したものを
使っているのだが、レスポンシブ・ウェブデザイン対応をやるついでに、ノリで
新しいバージョンにあげちまうかー。という事になった。

2系と互換性があるかとおもったら、無いものが結構あったのでメモ。

気になった変更点とか

bootstrap-responsive.css は無くなった

どうやら、統合された模様。IE8は、別途外部JSファイルを呼ぶ必要がある模様。

span-* が無くなった

代わりに、col-*, col-sm-*, col-lg-* になりました。
レスポンシブ・ウェブデザインを意識しているのか、サイズ別にグリッドの大きさを
指定できる模様。

components の名前変更とか

hero-unit と呼ばれてたもの (トップページにでかでかと表示させるタイトル用のやつ)
は、 jumbotron というものに変更。

さらばIE7, Firefox3.6サポート

そして滅びよ

すべての変更を確認したいときは?

以下で、公開というか、管理されている模様。
https://github.com/twbs/bootstrap/pull/6342

gradle-icon-512x512

オレオレGradleメモだよー

お仕事ではGroovy 使いかつ、XMLをチマチマ書いていくのが嫌いなので、
Maven や Ant ではなく、Gradle をビルドに使っています。

Java プロジェクトの場合は、プロジェクトのルートに下のような
build.gradle を準備して、Maven と同じ ディレクトレイアウトを
作ってやるだけで良いというのは、なかなか簡単です。

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

あとは依存追加したり、テストカバレッジを計測するために、
gradle-cobertura-plugin を導入したりしています。

課題

実装しているものの都合上、外部システムにHTTPでリクエストして
データを取得するというクラスが結構多いのですが、UnitTest の場合は
大抵、Mock にお願いする感じです。
(テストは Spock で書いていますので、Spock の Mock を活用する感じです。)

でも、たまに実際に、HTTPリクエストして返ってきたものを検証したい
という事もあり、HttpClient を Mock に差し替えず、実際に HTTP リクエストを
投げるテストも書いていたりします。

これを単純に src/test 下で書いてしまうと、 gradle build したときに、ネットワークや
データの都合などで見事にビルドが失敗したりします。
結果、Jenkinsのオッサンはその度に怒り狂い、平謝りをすることになります。

Jenkinsのオッサンには、UnitTest と、IntegrationTest的なものは
別々のタスクとして実行して貰いたい。ということで、新たにタスクを定義したい
わけです。

パッケージで分ける方法

とりあえず、ってことで今はパッケージで分ける方法を使っています。

apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.+'
}

test {
    exclude 'net/bucyou/integration/**'
}

task integrationTest(type:Test) {
    include 'net/bucyou/integration/**'
}

これで、 net.bucyou.integration.* にあるテストは build で実行されなくなります。
一方、integrationTest タスクを対象のパッケージ下のみをテストするように定義
しました。これで分離出来ました。

プラグイン使用+新しいディレクトリ分類を作る

よくよく探すと、integration-test plugin がありました。

これを使うと、 src/integration-test/(java|groovy|scala|resources) 
integrationTest のためのディレクトリとして捉えたタスクを追加してくれるっぽいです。

最初からこれ使ってればよかった・・・。