Watson's Blog

RubyMotion アプリを Jenkins でテスト実行してみよう

| Comments

この記事は RubyMotion Advent Calendar 2012 の 7 日目の記事です。

最近になってようやく Jenkins を使い始めてみたので、RubyMotion アプリを Jenkins でテスト実行する方法について調べてみました。

Jenkins をインストール

Homebrew を利用してインストールしました。

1
$ brew install jenkins

以下のコマンドを実行すると Jenkins が起動します。

1
$ java -jar /usr/local/opt/jenkins/libexec/jenkins.war

ログインしたときに自動的に Jenkins を起動したい場合には以下のコマンドを実行すると良いようです。

1
2
$ ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents
$ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

Jenkins をインストールしたマシンからのみアクセスする場合には問題がないのですが、別のマシンからもアクセスしたい場合には homebrew.mxcl.jenkins.plist を修正する必要があるようです。

1
2
3
4
5
6
7
8
9
10
11
12
diff --git a/homebrew.mxcl.jenkins.plist b/homebrew.mxcl.jenkins.plist
index 294b857..e4b892e 100644
--- a/homebrew.mxcl.jenkins.plist
+++ b/homebrew.mxcl.jenkins.plist
@@ -9,7 +9,6 @@
       <string>/usr/bin/java</string>
       <string>-jar</string>
       <string>/usr/local/opt/jenkins/libexec/jenkins.war</string>
-      <string>--httpListenAddress=127.0.0.1</string>
     </array>
     <key>RunAtLoad</key>
     <true/>

--httpListenAddress の行をざっくりと削除しましょう。

http://localhost:8080/ にアクセスすると、Jenkins で作業をおこなうことができます。

ジョブを作成

試しに https://github.com/HipByte/RubyMotionSamples の Timer アプリをテストするジョブを作ってみたいと思います。

とりあえず、サンプルを clone しておきます。

1
2
$ mkdir work
$ git clone git://github.com/HipByte/RubyMotionSamples.git

次に Jenkins でジョブを設定してきます。

  1. メニューの「新規ジョブ作成」を選択します。ここではジョブ名に「Timer」とし、「フリースタイル・プロジェクトのビルド」をチェックします。
    新規ジョブ作成

  2. 「プロジェクトの高度なオプション」でカスタムワークスペースを設定します。先ほど git clone したプロジェクトのパスを設定します。私の環境では /Users/watson/work/RubyMotionSamples/Timer というパスになります。
    カスタムワークスペースの設定

  3. 「ビルド」で「シェルの実行」を選択し、rake spec を実行します。 シェルスクリプト

ビルド実行

先ほど作成したジョブを実行してみます。メニューから「ビルド実行」を選択します。 ビルドした結果のコンソール出力を見てみましょう。

コンソール出力

1
2
3
4
5
6
+ rake spec
...
[1m  Simulate[0m ./build/iPhoneSimulator-6.0-Development/Timer_spec.app
*** stdout unavailable, output disabled
*** stderr unavailable, output disabled
Finished: SUCCESS

SUCCESS で終了しているのに、*** stdout unavailable, output disabled と結果が出力されません。

実行するスクリプトの修正

RubyMotion 1.28 で環境変数 SIM_STDOUT_PATHSIM_STDERR_PATH を設定すると標準出力と標準エラーの結果を指定したパスに保存されるようになったので、これを使ってみます。

ジョブに設定したシェルスクリプトを以下のように変更します。

1
2
rake spec SIM_STDOUT_PATH=/tmp/jenkins_output SIM_STDERR_PATH=/tmp/jenkins_error
cat /tmp/jenkins_output

ジョブを実行すると、コンソール出力が次のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
+ rake spec SIM_STDOUT_PATH=/tmp/jenkins_output SIM_STDERR_PATH=/tmp/jenkins_error
[1m     Build[0m ./build/iPhoneSimulator-6.0-Development
[1m  Simulate[0m ./build/iPhoneSimulator-6.0-Development/Timer_spec.app
+ cat /tmp/jenkins_output
The Timer view controller
  - has a timer label
  - starts a timer
  - increases the timer label value
  - resets the timer on each run

4 specifications (6 requirements), 0 failures, 0 errors
Finished: SUCCESS

ずいぶん良くなりました。

Jenkins はスクリプトの終了コードを見て、成功なのか失敗なのかを判断しているようです。テストがすべて成功したときだけ SUCCESS としてほしいところです。そこで次の run_spec というファイルを作成してパスが通っているところに配置し、Jenkins で実行するようにしました。

run_spec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/ruby

require "fileutils"
require "tempfile"
include FileUtils

stdout  = Tempfile.new("stdout") {}
stderr  = Tempfile.new("stderr") {}

# run spec
system "rake clean"
system "rake spec SIM_STDOUT_PATH=#{stdout.path} SIM_STDERR_PATH=#{stderr.path}"

# print result
result = File.read(stdout.path)
puts result

match  = result.lines.to_a.last.match(/(\d+) failures, (\d+) errors$/)
failures = match[1].to_i
errors   = match[2].to_i
if failures > 0 || errors > 0
  exit(1)
end

Jenkins の「シェルの実行」には run_spec とだけ記述すれば OK です。これでテストに失敗したときには Jenkins のステータスが赤く表示されるので分かりやすくなりました。

記事を書くまでに設定したのはここまでです。あとは定期的にテストを実行したり、テスト結果をメールで送信したりなどするとより良くなるのではないでしょうか。

Jenkins を使い始めたばかりでわからないことばかりなので、便利な使い方などありましたらお知らせください〜。

まとめ

Jenkins で RubyMotion アプリを実行するときには、環境変数 SIM_STDOUT_PATHSIM_STDERR_PATH を使いましょう。

Comments