テストはとことん自動で楽しく...。

ここまで、テストコードの実験のような気持ちでunitテスト、functionalテストと試してきた。それぞれのテストを実行する為には、rake test:units、またはrake test/functionalsとターミナルから入力して実行していた。しばらくすると、このコマンドはテストコードを書いたり、ソースコードを編集したら、常に繰り返し実行する運命にあることに気付いた。そして、なるべく短いサイクルで実施しておいた方が、問題が発生した時にその原因を特定し易くなるはずだ、ということも。
そのような経緯からか、Railsではシンプルに「rake」と入力して実行すると、testフォルダ以下のすべてのテストを実行する仕組みになっていた。(現状で「rake」を実行すると、unitテスト、functionalテスト両方の結果が表示された。)
ところが、さらに暫く使い続けていると、この「rake」というコマンドの実行さえも面倒だと感じるようになる。「人間、楽をしようとしたらキリが無い」とよく言われるが、Ruby界の優秀な人達は素晴らしい。「ZenTest」というテストツールを作り上げてしまった...。

テスト環境

ZenTestを利用する

インストール
  • インストールはとても簡単。
$ sudo gem install ZenTest
自動テスト
  • インストールしたら、以下のコマンドを実行するだけでOK。
$ autotest
  • これ以降、コードを変更するとテストが自動的に実行され、テスト結果が表示される。素晴らしい!
autotestの設定ファイル
  • ZenTestには「example_dot_autotest.rb」という設定ファイルの雛形が用意されていて、これを「.autotest」というファイル名でホームディレクトリにコピーして、その振る舞いを調整できる。
$ cp /Library/Ruby/Gems/1.8/gems/ZenTest-3.9.1/example_dot_autotest.rb ~/.autotest
  • コメントマーク「#」を削除して「require 'autotest/redgreen'」を有効にしてみると...
#a -*- ruby -*-

# require 'autotest/autoupdate'
# require 'autotest/camping'
# require 'autotest/cctray'
# require 'autotest/emacs'
# require 'autotest/fixtures'
# require 'autotest/growl'
# require 'autotest/heckle'
# require 'autotest/html_report'
# require 'autotest/kdenotify'
# require 'autotest/menu'
# require 'autotest/migrate'
# require 'autotest/notify'
# require 'autotest/pretty'
require 'autotest/redgreen'
# require 'autotest/screen'
# require 'autotest/shame'
# require 'autotest/snarl'
# require 'autotest/timestamp'

# Autotest::AutoUpdate.sleep_time = 60
# Autotest::AutoUpdate.update_cmd = 'svn up'
# Autotest::Emacs.client_cmd = 'emacsclient -e'
# Autotest::Heckle.flags 
」。
--テストが失敗に終わると赤の「
」。
>|
$ <span style="font-weight:bold;">autotest</span>
loading autotest/rails
hook run has been deprecated, use initialize
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -I.:lib:test -rtest/unit -e "%w[test/functional/slips_controller_test.rb test/unit/journal_test.rb test/unit/slip_test.rb].each { |f| require f }" | unit_diff -u
Loaded suite -e
Started
....../Users/bebe/railsapp/test_slip202/app/helpers/application_helper.rb:16: warning: default `to_a' will be obsolete
."[#<Slip id: 1, number: 1, total_yen: 1000, executed_on: \"2/14\", created_at: \"2008-03-04 16:11:14\", updated_at: \"2008-03-04 16:11:14\">, #<Slip id: 2, number: 2, total_yen: 2000, executed_on: \"2/15\", created_at: \"2008-03-04 16:11:14\", updated_at: \"2008-03-04 16:11:14\">]"
"[#<Journal id: 1, comment: \"test1\", yen: 1000, slip_id: 1, position: 1, created_at: \"2008-03-04 16:11:14\", updated_at: \"2008-03-04 16:11:14\">]"
/Users/bebe/railsapp/test_slip202/app/helpers/application_helper.rb:16: warning: default `to_a' will be obsolete
....
Finished in 0.427456 seconds.

11 tests, 22 assertions, 0 failures, 0 errors
<span style="color:#33FF00;">================================================================================</span>
|<


テスト結果の確認が、とても見易くなった!

**結果をGrowlで確認する
コードの修正が監視され、テストが自動実行される環境はなんて素晴らしいんだ!と感動して楽しみながらコードを修正していると...すぐに別の悩みが発生。テストは自動で実行されるが、そのテスト結果を確認する為に、コード編集中のエディタとターミナルの間で、頻繁にアプリケーションの切り替えをする必要性に気付く。これではせっかくのautotestの魅力が半減してしまう...。((広大なスクリーン環境なら、ウィンドウの配置を工夫すれば、コードを編集しながらターミナルでテスト結果を確認できるようにすることも可能かもしれない。しかし、MacBookのスクーリーンサイズでは...。))
しかし、Macには[http://growl.info/about.php:title=Growl]がある。もし、テスト結果をGrowlで通知できれば、アプリケーションの切り替えは不要になる。そして、autotestはGrowlにも対応していた!

***Growlのインストール
-まずは[http://growl.info/downloads.php:title=Growl Downloads]のページから、Growl 1.1.2 をダウンロードした。
-.dmgファイルを開いてGrowlのインストール。
-さらにExtrasフォルダ中のgrowlnotifyもインストールしておく。
>|
$ <span style="font-weight:bold;">cd /Volumes/Growl\ 1.1.2/Extras/growlnotify </span>
$ <span style="font-weight:bold;">./install.sh</span>
|<
-インストール後、MacBookを再起動しておいた。

***Growlに対応したautotestの設定
-設定ファイル「~/.autotest」を開いて、コメントマーク「#」を削除して「require 'autotest/growl'」も有効にした。
>|ruby|
#a -*- ruby -*-

# require 'autotest/autoupdate'
# require 'autotest/camping'
# require 'autotest/cctray'
# require 'autotest/emacs'
# require 'autotest/fixtures'
require 'autotest/growl'
# require 'autotest/heckle'
# require 'autotest/html_report'
# require 'autotest/kdenotify'
# require 'autotest/menu'
# require 'autotest/migrate'
# require 'autotest/notify'
# require 'autotest/pretty'
require 'autotest/redgreen'
# require 'autotest/screen'
# require 'autotest/shame'
# require 'autotest/snarl'
# require 'autotest/timestamp'

# Autotest::AutoUpdate.sleep_time = 60
# Autotest::AutoUpdate.update_cmd = 'svn up'
# Autotest::Emacs.client_cmd = 'emacsclient -e'
# Autotest::Heckle.flags << '-t test/**/*.rb'
# Autotest::Heckle.klasses << 'MyClass'
# Autotest::Shame.chat_app = :adium
Mac OSX 10.5 Leopardでgrowlnotifyを利用する為に

もしOSX 10.4 Tigerなら、この状態でautotestを実行すれば、見事に結果がGrowlで通知され、感動できると思う。しかし、OSX 10.5 Leopardではgrowlnotifyが完全には対応していないようだ...。そのため、参考ページで紹介されている通り、以下のようにやってみた。

  • ファイル名「growlnotify」を「growlnotify.wrapped」に変更する。
$ mv /usr/local/bin/growlnotify /usr/local/bin/growlnotify.wrapped
  • 上記の変更後、新たに実行権限を持った「growlnotify」を作成し...
$ touch /usr/local/bin/growlnotify
$ chmod a+x /usr/local/bin/growlnotify
  • その内容を以下のシェルスクリプトで保存しておく。
      • 半角¥(円マーク)は、半角\(バックスラッシュ)に置き換える必要あり。
#!/bin/bash

# growlnotify leopard bug workaround
# 

list_args()
{
    for p in "$@"
    do
        if [ "${p:0:1}" == "-" ];then
            echo -n "$p "
        else
            echo -n "\"$p\" "
        fi
    done
}

argstr=$(list_args "${@:$?}")

echo "-H localhost $argstr" | xargs /usr/local/bin/growlnotify.wrapped


  • もはや、上記のラッピング技は不要だが、もっと単純に以下のエイリアス設定でも良さそう。
$ alias growlnotify='/usr/local/bin/growlnotify.wrapped -H localhost'
参考ページ

素晴らしいページに感謝です!

何をやっているのか?
  • Growlにはネットワーク経由で通知されたメッセージを表示するという機能もあり、OSX 10.5環境のgrowlnotifyはネットワーク経由の通知だけは受け取って、正常に処理できるようだ。
  • 元々のコマンドgrowlnotify. wrappedを実行する前に、シェルコマンドですべての呼び出しをネットワーク経由のgrowlnotifyに変換してから実行しているようだ。
Growlの環境設定
  • ネットワーク経由の通知になるため、Growl環境設定は以下のようにしておく。
    • 一旦、autotestがGrowlに登録されたら、「リモートアプリケーション登録を許可」のチェックは外してしまって問題ない。

  • そしてレベルが「緊急」の通知については赤く表示される設定にしておいた。

  • これでautotestを実行すると、Growlで以下のように通知されるようになった。


何だかテストが楽しくなってきた!

参考ページ

素晴らしいページに感謝です!