2011-03-06 17:33:18
Ruby 以外のプログラムを書いていると, 「RSpec で spec が書けない」というだけの理由で, 億劫になってしまうことがあります.
RSpec で JavaScript の spec が書ければ... そう思って, やってみました.
まずは実際のコードを説明なしに紹介し, 環境構築手順や, 解説については後述します.
テスト対象 (System Under Test)
今回はこの JavaScript のコードを対象に, spec を書いてみます.
とりあえずは「RSpec で JavaScript の spec が書けるのか」という検証が目的なので, シンプルなもので十分でしょう.
t-wada さんのRSpec の入門とその一歩先へをそのまま JavaScript にしてみたようなものです.
detect メソッドに渡す文字列の中に, コンストラクタに渡された単語が含まれるか, を検証するだけの簡単なオブジェクトです.
$ js
Rhino 1.7 release 2 2010 09 15
js> load("message_filter.js")
js> var filter = new MessageFilter("foo");
js> filter.detect("foo bar baz");
true
js> filter.detect("Hello, World!");
false
spec
上記のコードをテストするための spec です.
MessageFilter というクラスは Ruby 上で定義されているわけではないので, ここでは Symbol 型を利用しています.
これを実行すると, 以下のようになります.
$ rspec -fs message_filter_spec.rb
MessageFilter with argument "foo"
should detect from "foo bar baz"
should detect from "Hello World!"
Finished in 0.40217 seconds
2 examples, 0 failures
一応の動作は確認できましたね.
環境の構築
今回は以下のような環境を使用しています.
OS は Ubuntu 10.10 です.
$ ruby -v
ruby 1.8.7 (2011-02-18 patchlevel 334) [i686-linux]
$ rspec -v
2.5.1
$ gem list # 一部省略
*** LOCAL GEMS ***
harmony (0.5.6)
johnson (2.0.0.pre3)
rspec (2.5.0)
rspec-core (2.5.1)
stackdeck (0.2.0)
普段は Ruby 1.9.2 を使用しているのですが, 今回使用する harmony という gem の依存ライブラリである johnson が, 1.9.x ではインストールできないようなので, 1.8.7 を使用しています.
RVM を利用して複数の Ruby 環境を切り替えられる環境であれば, さほど問題は無いでしょう.
以下のようにインストールします. (Ruby, RVM のインストールは省略)
$ gem install stackdeck
$ gem install johnson -v "2.0.0.pre3"
$ gem install harmony
$ gem install rspec
harmony のインストール時には, 依存ライブラリである stackdeck と johnson も一緒にインストールされるべきですが, 現在は問題があってうまくできないようです.
とりあえず手動でインストールしておけば問題ありません.
どういう仕組みで動いているのか
Johnson が Ruby 上での JavaScript (SpiderMonkey) の実行環境を提供し, Harmony はそれをラップした DSL, とのことです.
Harmony::Page オブジェクトが .js ファイルを読み込んだコンテキストを保持し. x メソッド (execute_js メソッドのエイリアス) でプログラムを実行することができます.
x メソッドで実行した JavaScript プログラム中, 最後に評価された値が返り値として Ruby に渡されます.
(ただし, オブジェクトは返らないらしい)
問題点
- 可読性が低い
JavaScript のコードを文字列リテラルで書かざるを得ないこともあり, とても読みやすいとは言えないでしょう.
RSpec はメタプログラミングにより "Test as Documentation" (ドキュメントとしてのテスト) を簡単に書かせてくれるはずですが. ここではその力を発揮できていません.
- Object の検証ができない
前述のとおり, Harmony は JavaScript の Object 型の値を Ruby に渡してくれません.
JavaScript における Object は, ハッシュ変数として使われることもあり, これを検証できないのは致命的でしょう.
とはいえ, オブジェクトがメソッドを持っていた場合, それを Ruby でどう表現するか, という問題もあり, 解決は難しいでしょう.
上記の理由から, 実際に運用・保守していくのは難しいでしょう.
最近は HTML5 によるスマートフォンアプリ作りに挑戦しようとしているのですが, TDD/BDD のフレームワークに何を使うべきか, で迷っています.
今のところは次作の簡単なフレームワークで検証していますが, さすがにずっと運用するわけにはいかないので, デファクトスタンダードなものが知りたいところです.
いいのを知っている方は是非 @yuya_takeyama まで教えてください.
JavaScript におけるテスト技法については, 2011/03/08 (Tue) に Test.js というイベントでおもしろい話が聞けそうです.
是非参加したいところですが, ATND への参加登録が遅くなったので絶望的な状態です...
この記事を LT する発表者としての参加, なんてのはダメですよねぇ...
Ust で我慢します.
2011-02-08 15:01:06
Web エンジニアであれば, Apache のアクセスログを tail -f で流しながら確認することは多いのでは無いでしょうか.
通常は白黒で非常に見づらいと思いますが, 以下の記事を参考に, カラフルにしてみました.
RubyでANSIカラーシーケンスを学ぼう! (hp12)
今回用意したコードはこちら.
shebang を合わせてもたった 4 行です.
こちらはログフォーマットに依存するので, ご注意ください.
combined や vhost_combined といったログフォーマットを前提としています.
以下のようにして使用します.
$ tail -f /var/log/apache/path_to_access_log | ./colorize.rb

実際の使用例は, 右の画像の通りです.
(このブログのアクセスログです. IP 等は枠外にはみ出させました.)
tail -f なので, このようなログがずっと流れてきます.
私の場合は, リクエストメソッド, リクエストパス, ステータスコードに色付けしています.
上記の記事では HighLine や TermColor といった gem を利用していますが, 私の場合はこのワンライナーの正規表現で十分だったので, それで済ませてしまいました.
それぞれの用途によっては, さらなるカスタマイズや, より一般化されたツール化なども考えられると思いますが, とりあえず一例として.
あとはこれを, 以下のような less の使い方に対応させる方法があればいいのですが, 私がやった限りはわかりませんでした...
less の tail -f モード的な何か (YoshioriのBlog)
どなたか, いい方法があれば是非教えてください...
それでは今日はここまで.