Augmented Usamimi

it { is_expected.to be_blog.written_by(izumin5210) }

GroovyとSpockでテスト書く話してきた #potatotips

いってきた.#19 - #20 - #21 - #22と4連続当選らしい.

connpass.com

内容

最近はBLEネタが多くてBLEオジサン化してたので,趣向を変えてテストネタ.

speakerdeck.com

Spock

SpockRSpecなどから影響を受けたらしい,すごい柔軟でいい感じのDSLでテスト(Spec)が書けるというすばらしいテスティングフレームワークである.

github.com

特徴は色々あるが,個人的に大きいと思っているのは以下の2つ:

  • パラメタライズドテストが超いい感じにかける
  • テスト落ちた時のメッセージが見やすい(Power Assert!)

Parameterized test

Parameterized Test とは、まさに似たようなテストメソッドをテストデータだけ変えて複数件実行することができる手段で、多くの場合テスティングフレームワーク拡張機能として提供されています。

これであなたもテスト駆動開発マスター!?和田卓人さんがテスト駆動開発問題を解答コード使いながら解説します~現在時刻が関わるテストから、テスト容易性設計を学ぶ #tdd|CodeIQ MAGAZINE

JUnitでパラメタライズドテストを書くと以下のようになる.省略してもこの分量.

@RunWith(Theories.class)
public class GreeterTest {
    public static class Fixture { /* ... */ }

    @DataPoints
    public static Fixture[] getParameters() { return new Fixture[] {
        new Fixture("morning", "Good morning"), /* ... */ };
    }

    @Theory
    public void say(Fixture fixture) throws Exception {
        Greeter greeter = new Greeter(); assertEquals(fixture.getExpected(), greeter.say(fixture.getArg()));
    }
}

↑これが ↓こうなる

class GreeterSpec extends Specification {
    def "#say()"() {
        expect:
        expected == new Greeter().say(period)

        where:
        period      | expected
        "morning"   | "Good morning"
        "afternoon" | "Hello"
        "night"     | "Good night"
    }
}

これだけで導入する理由になりませんかね??? とくに入力により出力が一意に定まるようなメソッドやユーティリティ関数なんかはテストがこれだけで良くなるかもしれない.

Groovy

Spockを利用したいなら,テストは必然的にGroovyで書くことになる.

ちゃんと型を意識して安全に実装しないといけないような本体コードに対し,とりあえずちゃんとassertionができればあとはゆるふわにさくさく書いていきたいテストコードを記述していくにあたり,ゆるふわ言語であるGroovyはわりと適しているんじゃないかと思った. 宣言で型を明示しなくてもとりあえずよしなに型付けてくれて補完ちゃんとだしてくれる,そのゆるふわ性がとても楽でいい.頭使わなくていいの最高である.

Android × Groovy

ここがわりとネック.

SNAPSHOTだけでもいいから早く出してほしい….

本体コードとテストコードを別言語にするということ

JS界では本体コードをTypeScript,テストはECMAScript2015で記述するという宗派がある. テスト書くのにいちいち型アノテーションとか書くの面倒くさいといった理由である.

書きたいのはアプリケーションの本体コードであってテストコードではないので,テストコードに無駄なリソースは割きたくない(テスト書くの自体は楽しいんだけど:p).だからテストはゆるふわ言語でサクッと書いちゃうのは結構いいんじゃないかと思う.

とくにJUnitJava) → Spock(Groovy)はそのコード削減量とか複雑さの解消度合いがTypeScript → JavaScript(ES2015)の比ではないので,テスト記述にかかるコスト(おもに精神的コスト)も段違いに安く済む気がしている.

雑記

konifarさんにいい感じに褒めてもらえて嬉しい.

konifar.hatenablog.com

東京に移ってから,コミュニティへの恩返しの意味も込めて月1ペースで前に出て喋るようにしている. 最近では「Qiitaで記事よく見ます!」「インターネットでよく見ます」「いつも発表聞いてます!」みたいなことをときどき言われるようになってきた. この調子で名前売っていって,将来は楽しくコード書いて暮らしていくぞという感じ.