くりにっき

フルスタックキュアエンジニアです

TDDBC福岡にTAとして参加してきました #tddbc

繁忙期は飛行機が高いので帰省ついでに行って来ました。

LTについて

1日目と2日目にそれぞれやってました

1日目:Travis CIについて

ほとんどのチームがGithubで開発してるということで、Githubとの親和性の高いTravis CIの紹介をしてました。

参考:GithubにあるリポジトリをTravis CI連携する手順 #junitbook - くりにっき

2日目:Groovy + Spockについて

Groovyが1チームもいなかったので昼食を食べながらGroovyで課題をやってみました。
https://github.com/sue445/wikiengine-spock

JUnitでもParameterizedやTheoriesを使えばParamerize系のテストはできますが、Spockだと断然見やすいですね

class WikiEngineSpec extends Specification{
    def "format(#line) == #expected"(){
        setup:
        def sut = new WikiEngine()

        expect:
        sut.format(line) == expected

        where:
        line                    | expected
        "_italic_"              | "<i>italic</i>"
        "*bold*"                | "<b>bold</b>"
        "= Heading ="           | "<h1>Heading</h1>"
        "== Subheading =="      | "<h2>Subheading</h2>"
        "=== Level 3 ==="       | "<h3>Level 3</h3>"
        "==== Level 4 ===="     | "<h4>Level 4</h4>"
        "===== Level 5 ====="   | "<h5>Level 5</h5>"
        "====== Level 6 ======" | "<h6>Level 6</h6>"
        "_italic_ and *bold*"   | "<i>italic</i> and <b>bold</b>"
        "other string"          | "other string"
    }
}

https://github.com/sue445/wikiengine-spock/blob/master/src/test/groovy/tddbc/WikiEngineSpec.groovy

あと、GroovyのPowerAssertの結果も見やすいです

Condition not satisfied:

sut.format(line) == expected
|   |      |     |  |
|   |      |     |  <h1>Heading</h1>
|   |      |     false
|   |      |     1 difference (94% similarity)
|   |      |     <h1>Heading( )</h1>
|   |      |     <h1>Heading(-)</h1>
|   |      = Heading =
|   <h1>Heading </h1>
tddbc.WikiEngine@658782a7

	at tddbc.WikiEngineSpec.format(#line) == #expected(WikiEngineSpec.groovy:18)
groovyの特徴

LTではspockとPowerAssertの素晴らしさしか紹介できなかったのでその他のgroovyの特徴を紹介しておきます

  • メソッド名をStringで定義できるため、Javaのメソッド名の制限*1にとらわれることがない
  • セミコロンを省略できる
  • チェック例外は非チェック例外にラップされるため、テストメソッドに throws Exception を書かなくていい
  • switch文に正規表現リテラルを渡せる
    String format(String line){
        switch (line){
        case ~/_(.+)_/:
            return line.replaceAll(/_(.+)_/, /<i>$1<\/i>/)
        case ~/\*(.+)\*/:
            return line.replaceAll(/\*(.+)\*/, /<b>$1<\/b>/)
        default:
            return line
        }
    }

https://github.com/sue445/wikiengine-spock/blob/76decd61e8976b61f2e2335dd4cc67707ed03758/src/main/groovy/tddbc/WikiEngine.groovy

  • mapの記述が簡単
  • rubyでお馴染みのeachやinjectが使える
    String format(String line){
        def wikiFormats = [
                /_(.+?)_/                 : /<i>$1<\/i>/,
                /\*(.+?)\*/               : /<b>$1<\/b>/,
                /======\s*(.+?)\s*======/ : /<h6>$1<\/h6>/,
                /=====\s*(.+?)\s*=====/   : /<h5>$1<\/h5>/,
                /====\s*(.+?)\s*====/     : /<h4>$1<\/h4>/,
                /===\s*(.+?)\s*===/       : /<h3>$1<\/h3>/,
                /==\s*(.+?)\s*==/         : /<h2>$1<\/h2>/,
                /=\s*(.+?)\s*=/           : /<h1>$1<\/h1>/,
        ]

        wikiFormats.inject(line){ work, entry ->
            work = work.replaceAll(entry.key, entry.value)
            work
        }
    }

https://github.com/sue445/wikiengine-spock/blob/91f960e4f7aafad8ebd854652e900b1b72c47cfc/src/main/groovy/tddbc/WikiEngine.groovy

個人的振り返り

  • TDDBCのKPTで毎回「環境構築に時間がかかった」というProblemが上がっていたのですが、前回のTDDBC東京以降有志で協力して GithubのTDDBC Organization でスケルトンをいくつか作っていたため、今回はそういうProblemはほとんど上がってなかった *2
    • forkしてcloneしていくつか環境設定用のコマンドを叩けばすぐに課題を始められる状態になるため、TDDと関係ない部分でハマる要素が1つなくなったのでスケルトンを用意してよかったと思います
    • githubのnetwork graphを見るだけでどんなチームがどんなコードを書いたのかひと目で分かるのがいいですね
    • Javaのスケルトンを作ってくれた @ さんありがとうございます!
    • スケルトンがなかったPHPやObjective Cに関しては正直スマンカッタ
  • AZusaar!! を知ってる人がいてよかったw
  • 土日遠征する場合は前後に休みをいれるべき(反省)

*1:先頭に数字が使えない、ドットなど一部の文字が使えない

*2:Keepにも「スケルトンがあって便利だった」というのは特に上がってなかったけどw