TDD Boot Camp 横浜で初めてGroovy触ったらかっこよすぎワロタwwww #tddbc

1日たってしまいましたが、11/06にTDD Boot Camp 横浜に参加してきました。詳しい記事は、id:absj31さんの記事が素晴らしくまとまっているので、ご覧くださいませ。
TDD Boot Camp 横浜に参加してきた #tddbc - Diary of absj31
TDD BCの感想と、Groovyを初めて触った感想です

Groovyペアに立候補した理由

  • 「募集」をしているわけで、立候補すれば、その場でペア成立
  • Groovyを触ったことがなくても大丈夫という前提
  • プログラミング言語好きとしては、Groovy触ってみたかった
  • 普通なら、師匠は直々に、言語のフォースを教えくれない
  • 運営の方と、TDDやったほうが身につきそう!

たしか、こんな理由だったと思います。打算と興味が五分五分といったところでしょうか。運営の方が、Groovy本を持ってきてくれて、 パラパラと見た第一印象は、「Javaとrubyの間の子か…」ぐらいで、そのGroovyという言語の独特のコンセプトはわからなかったです。

Javaと寄り添う言語としてのGroovy

Groovyの一つの大きな特徴は、Groovy上からJavaのコードをごく自然に呼び出せることとLLならではの、柔軟な構文を作り出せることです。これは、TDDのメインであるテストコードの実装で力を思う存分発揮してくれます。TDDで、出せれたお題は、

  • 入力として、選手の打席数と打数と安打数を受け取り、選手の打率を計算できること。
  • 打率は小数第4位で四捨五入すること。
  • 打席数が0の場合は、打率を計算しないこと。(Javaならnull、Rubyならnil相当)
  • 打席数が0でなく、打数が0の場合は「0.000」と計算すること。

Groovyハッカーの@nobeansさんとペアプロさせて頂きました。全ソースコードは@nobeansさんがgitに上げてくださっています。
https://github.com/nobeans/tddbc-yokohama-201111/tree/master/src
リンクからコード少し引用してしまいました…ごめんなさい><;TDDなので、テストコードの一部です。Spockを使いました。

import spock.lang.*

class PlayerSpec extends Specification {

  def "打席数と打数と安打数を受け取り、打率を計算する"() {
    setup:
    def player = new Player(box:box, atBat:atBat, hit:hit)

    expect:
    player.getBattingAverage() == battingAverage

    where:
    box | atBat | hit | battingAverage
    3   | 2     | 1   | 0.5
    4   | 4     | 1   | 0.25
  }
 def "打席数と打数と安打数を受け取り、小数第四位で四捨五入する (無限小数、四捨)"() {
    setup:
    def player = new Player(box:3, atBat:3, hit:1)

    expect:
    player.getBattingAverage() == 0.333

  }

  def "打席数と打数と安打数を受け取り、小数第四位で四捨五入する (五入)"() {
    setup:
    def player = new Player(box:515, atBat:455, hit:135)

    expect:
    player.getBattingAverage() == 0.297
  }

  def "打席数が0の場合は、打率を計算せずにnullを返す"() {
    setup:
    def player = new Player(box:0, atBat:455, hit:135)

    expect:
    player.getBattingAverage() == null
  }

  def "打数が0の場合は、0.000を返す"() {
    setup:
    def player = new Player(box:3, atBat:0, hit:0)

    expect:
    player.getBattingAverage().getClass() == BigDecimal.class
    player.getBattingAverage().scale() == 3
    player.getBattingAverage() == 0.000
  }

}

続いて、GroovyでPlayerクラスを実装しました。

import java.math.*

class Player {
    int box
    int atBat
    int hit

    def getBattingAverage() {
        if (this.box == 0) {
             return null
        }
        if (this.atBat == 0) {
             return 0.000
        }
        (hit as BigDecimal).divide(atBat, 3, RoundingMode.HALF_UP)
    }
}

可読性とメンテナンスのしやすさ

ソースコードを書いていくときに、「こwwwれwwwはwww」とニヤニヤでした。なにより、テストコードがふつくしい…
テストコードのメンテナンス性は、あまり語られないのですが、テストコードが、メンテナンスされていないと、TDDのプロセスを殺してしまうと僕は考えています。でも、TDDの大きな障壁にもなってるんじゃないかと思うくらい、テスコードってTDD初心者にとっては、メンテナンスしにくいんです。実装のスピードは体感で確実に落ちる焦りもあるので、テストコードにかける時間は、できるだけ短くしたいと思ってしまうのが(私も含めて)初心者の性でしょう。結果、メンテされないテストができあがると。

ひとつの仕様に対して、一つのテストケースでいいのがどれほど素晴らしいことか…Groovyは、JavaでのTDDを確実にDrivenしてくれます。Groovyを初めて触りましたが、Groovyのパワーを知るには十分でした。(これは、Groovyのパワーの一面でしかないでしょう)

id:t-wadaさんのコードレビューの中で単語として出てきた、4Phaseテストも「それ、Groovyでいうと、setup,expect,whereじゃん…」という感じでした(進研ゼミか)。Unitテストのベストプラクティスを地で行く言語に思えます。そして、ひとつの仕様に対して、いろんな数を突っ込むテストを簡単にかけるので、メンテナンス性、可読性ともに◎

Groovyの良さをJavaを触っている人に伝えるなら

  • 今すぐ導入できます。javaの言語の一部のように、動きます。
  • javaの言語の特徴を受け継いでいるので、プロジェクト全体としてのコードの統一感は崩れない
  • 「javaのコードをメンテナンスする」用途に非常に向いている。テストコードにぜひ
  • 今時の言語をちょろちょろ触っているニワカ野郎(代表作:私)でも学習コストは非常に低い
  • Groovy楽しい

ちょろちょろ触っている程度が、資産として生かされるというwww恐ろしい子www「他言語と寄り添う」言語というのが僕には、とても新鮮でした。

運営について

抽選について

運営の方々が気になさっていらっしゃいましたので…私個人的には、非常に助かりました。仕事が一段落したときに申し込みページがすでにいっぱいになってしまっていたので、今回参加できたは、抽選のおかげです。

多言語でのTDD

とても成功していると思います。他の言語のテストコードを見比べることができるのは、とても面白いです。

ペアプログラミング

素晴らしい体験でしたが、改善するとすれば使うエディタは今後、注意しないといけませんね

気づきとすこし疑問に思ったところ

自分が思っていたのよりも、タスクの粒度がずっと細かい

id:t-wadaさんがTDDを説明してくださる機会があったのですが、組み込み関数でも仕様への理解が怪しいところは、テストコードとして残していました。@nobeansさんとペアプロさせていただいた時も、少しの変更でもテストを走らせていました。僕が実装をしようとして止められる機会が結構ありました。TDDならではのタスク粒度があるのだろうと思います。

TDDにやり慣れている方は、考慮漏れに強い気がする

これは、@nobeansさんとペアプロさせていただいたときに感じたことですが、テストを書いたときに「こういう時は、どうなる?」という問いかけがけっこうありました。自分では、全く考慮していなかったことがたくさんあって、「どうしたら、そういうふうに気づくんだ?」と思うことがありました。慣れなんだろうか…そう思いたいものです :)

意識的にRED、意識的にGREEN

プログラミングを書いている人間が、「これは、赤なはず…これは、緑だよね?」というようにプログラミングという行為を制御できそうなかんじが、TDDの大きな特徴だと思いました。

最後に

主催して下さった @setoazusa さん、素晴らしい基調講演をして下さった id:t-wada さん、スタッフの皆さん、そして参加者の皆さん、素晴らしい時間をありがとうございました。すごい楽しかったです。

Groovyを啓蒙くださった@nobeansさん、@pocketberserkerさんありがとうございました。Groovyかわいいよ!Groovy!