Gradle+guardでGHUnitの自動テスト環境を構築してみた

GHUnitは,Mac OSX/iOSのかなり高機能なテストフレームワークである.これには,以下の様な特徴がある
・非同期通信のテストが容易にできる
iPhone実機・シミュレータで動作確認ができる

ただ,デメリットの一つとして,GHUnitは通常シミュレータ(又は実機)上で立ち上げてボタンを押さなければ,テストが実行されない.というわけで,保存された瞬間にコマンドライン上でテストの結果を表示させたいと思います.

GHUnitを導入する

GHUnitの導入です.CocoaPadsを使うと導入が非常に楽です.使うことを非常におすすめします.

CocoaPods を導入して GHUnit と OCMock を使って単体テストを書く|クラスメソッド株式会社 開発ブログ を参照に,GHUnitを導入することができます.

コマンドライン上で実行する

Running from the Command Line
GH-Unitのコマンドライン実行について
を参考にコマンドライン上で実行を導入することができます

そして,以下のコードworkspaceとschemeを書き換えて実行できることを確認してください.

$ GHUNIT_CLI=1 xcodebuild ONLY_ACTIVE_ARCH=NO -workspace YUER_WORKSPACE.xcworkspace -scheme YUER_SCHEME -configuration Debug -sdk iphonesimulator build

gradleを導入する

gradle は 汎用ビルドツールです.Groovyでビルドスクリプトを記述することができ,オブジェクト指向のリッチなドメインモデルを使用可能です.

gvmをインストールする
$ curl -s get.gvmtool.net | bash

でインストールして再起動してください.

groovyとgradleをインストールする

gvmがインストールしてあるのでコマンド一発でインストール出来ます

$ gvm install groovy
$ gvm install gradle
gradleで実行する

workspaceと同じディレクトリに置き,二行目のschemeを書き換えて実行してください.

// build.gradle
def scheme = 'Tests'

task test(type:Exec) {
    File file = workingDir
    def workspace = file.listFiles().findAll{it.name.endsWith('.xcworkspace')}[0]
    commandLine'xcodebuild','ONLY_ACTIVE_ARCH=NO','-workspace',workspace,'-scheme',scheme,'-configuration','Debug','-sdk','iphonesimulator','build','GHUNIT_CLI=1'
    standardOutput = new ByteArrayOutputStream()
}
test << {
    def list = standardOutput.toString().split("\n").toList()
    def indexStarted = list.findIndexOf{it ==~ /Test Suite.+/}
    def indexFailed = list.findIndexOf{it ==~ /Failed tests.+/}
    def testResult = list.subList(indexStarted, indexFailed+1)
    print testResult.inject(''){t,s->t+s+'\n'}
}
$ gradle -q test

workspaceは自動的に取ってこれるようにし,更にビルドメッセージなどの要らないメッセージは削除するようにしてあります.
これで簡単にビルドすることができるようになった

guardで自動化する

Guardはファイルの変更を監視し,変更があることに何らかの処理を行うツール.
これを使ってgradleを実行してもらいましょう

Guardの導入
$ gem install guard

これでインストールされました.

Guardfileの編集

プロジェクト内にあるファイルが変更された場合,自動的にビルドするように設定し,実行します

# Guardfile
guard 'shell' do
  watch(%r{.+\.(h|m|c|mm)$}) { `gradle -q test`}
end
$ guard

これで,自動的にテストを走らせてくれるはずです.実際にファイルを変更して確かめてみてください.

まとめ

Jenkinsでビルドするのもいいと思ったのですが,手元で実行する方法も欲しかったのでやってみました.もっとスマートな方法が見つかったら,書こうと思います.