GeekFactory

int128.hatenablog.com

SpockのPollingConditionsがE2Eテストで便利

Spockの PollingConditions が便利だったのでメモです。 PollingConditions は条件を満たすかタイムアウトになるまで評価を繰り返してくれます。E2Eテストで別スレッドでサーバを起動してサーバがreadyになるまで待つといった場合に便利です。

import spock.lang.Specification
import spock.util.concurrent.PollingConditions

class ServerSpec extends Specification {
    def "server should listen on given port"() {
        given: '空きポートで待ち受けるWebサーバを生成する'
        int port = pickUpFreePort()
        def server = new Server(port)

        when: '別スレッドでWebサーバを実行する'
        Thread.start { server.run() }

        then: 'Webサーバが応答を返すまでポーリングする'
        new PollingConditions(timeout: 3).eventually {
            try {
                def response = new RESTClient("http://localhost:$port").get(path: '/') as HttpResponseDecorator
                assert response.success
            } catch (HttpHostConnectException e) {
                assert false, e.localizedMessage
            }
        }
    }

    static int pickUpFreePort() {
        def socket = new ServerSocket(0)
        def port = socket.localPort
        socket.close()
        port
    }
}

リトライの間隔などはコンストラクタの引数で指定できます。詳細はSpockドキュメントの PollingConditions を参照してください。

下書きしてから9ヶ月ぐらい放置してた記事を発掘したので公開しました。たぶん今年初め頃に instagitinstahttp とか作ってて書いた記事ではないかと。。。と思って探したら instagitのテストコード で使っていました。

github.com

github.com