RSpec は Ruby の BDD(Behavior Driven Development). テストフレームワークの1つです。
Install RSpec
% sudo gem install rspec
Quickstart
下の方にあるサンプルコードのディレクトリ構成です。
lib/ ディレクトリに開発するライブラリを配置。
spec/ ディレクトリに spec(テスト) コードを配置。
- sample_project/
- lib/sample.rb サンプルのライブラリ
- spec/
- sample_spec.rb sample.rb のテストプログラム
- spec_helper.rb すべてのテストで共通する処理を書くスクリプト
ディレクトリを作成
まず、プロジェクトのディレクトリを作成して、その中に lib/ と spec/ ディレクトリを作成します。
% mkdir sample_project % cd sample_project % mkdir lib % mkdir spec
spec_helper.rb を作成
sample_project/spec/spec_helper.rb :
# encoding: utf-8 require "rubygems" require 'test/unit' require "spec" $LOAD_PATH << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__)) __END__ Needed "require 'test/unit'" before "require 'spec'" due to an error below with autospec. /home/ice/.gem/ruby/1.8/gems/rspec-1.1.11/lib/spec.rb:25:in `exit?': undefined method `run?' for Test::Unit:Module (NoMethodError) from /home/ice/.gem/ruby/1.8/gems/rspec-1.1.11/lib/spec/runner.rb:192:in `register_at_exit_hook' from spec/messa/db/clawler/page_data_spec.rb:9 ref: http://www.ruby-forum.com/topic/170889
spec(テスト) プログラムの作成
開発するライブラリの方ではなく、テストプログラムの方を先に作成。
このテストは lib/sample.rb 内の Sample クラスの mix() メソッドをテストするプログラムです(まだ作ってないけど)。
そして作成したら↓の様にテストを実行します :
% cd sample_project % spec -c spec/sample_spec.rb
sample_project/spec/sample_spec.rb :
# -*- coding: utf-8 -*- require File.expand_path(File.join('.', 'spec_helper'), File.dirname(__FILE__)) require 'sample' # for lib/sample.rb describe Sample, "When mix two numbers," do before(:each) do @sample = Sample.new end it "should calculate as +" do @sample.mix(1, 1).should == 2 @sample.mix(100, 11).should == 111 @sample.mix(10, -109).should == -99 end end
RSpec は Ruby の Ojbect を拡張しているので、普段使ってるクラスに should などの見慣れないテスト用メソッドが追加されてます。
should メソッドはオブジェクト(変数)をチェックする用のメソッドで下のような漢字の使い方をします。
100.should == 100 1000.should >= 1 true.should be_true false.should_not be_true
should() の最初のパラメータ (== とか >= とか be_true) はマッチャー(matcher) と呼ばれているらしい。
詳しいことは次回以降のエントリーで。
結果 :
% spec -c spec/sample_spec.rb /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- sample (LoadError) from /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:31:in `require' from ./spec/sample_spec.rb:4 from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load_files' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `each' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `load_files' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/options.rb:98:in `run_examples' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/command_line.rb:10:in `run' from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/bin/spec:4 from /usr/bin/spec:19:in `load' from /usr/bin/spec:19
spec を実行するとエラーが発生するはずです。
テスト対象のライブラリ lib/sample.rb をまだ作成してないので当然ですが・・・。
でもテストファーストなので失敗してもOKです。
テスト対象のライブラリを作成
先ほど発生したエラーは 「sample なんてファイルねえよ」 とか。(“no such file to load — sample (LoadError)“.)
なので sample_project/lib/sample.rb をとりあえず作成します。中身はカラのままでOK。
そして spec を実行して、失敗させます。
% spec -c spec/sample_spec.rb
./spec/sample_spec.rb:6: uninitialized constant Sample (NameError)
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:14:in `load_files'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `each'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/example_group_runner.rb:13:in `load_files'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/options.rb:98:in `run_examples'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/runner/command_line.rb:10:in `run'
from /usr/lib/ruby/gems/1.8/gems/rspec-1.1.11/bin/spec:4
from /usr/bin/spec:19:in `load'
from /usr/bin/spec:19
またまたエラーが発生し、今度は 「Sample なんて定数ないよ」とか。 (“uninitialized constant Sample (NameError)“)
ファイルの中身を以下のように記述 :
sample_project/lib/sample.rb :
class Sample end
spec を実行
% spec -c spec/sample_spec.rb F 1) NoMethodError in 'Sample When mix two numbers, should calculate as +' undefined method `mix' for #<Sample:0xb7adbbac> ./spec/sample_spec.rb:12: Finished in 0.061528 seconds 1 example, 1 failure
今度は 「メソッド mix() 未定義だ」とか。 (“undefined method `mix’ for #<Sample:0xb7adbbac>“)
なので、メソッド mix() を定義します :
sample_project/lib/sample.rb
class Sample def mix(item1, item2) end end
実行結果 :
% spec -c spec/sample_spec.rb F 1) 'Sample When mix two numbers, should calculate as +' FAILED expected: 2, got: nil (using ==) ./spec/sample_spec.rb:12: Finished in 0.026445 seconds 1 example, 1 failure
次はエラーではなく mix() の戻り値が期待したものと違った様子。(“expected: 2, got: nil (using ==)“)
メソッド mix() を以下のように実装します :
sample_project/lib/sample.rb
class Sample def mix(item1, item2) return item1 + item2 end end
spec を実行
% spec -c spec/sample_spec.rb . Finished in 0.030934 seconds 1 example, 0 failures
spec がパスしました。
こんな感じでテストを書いて、実装、テストというサイクルを繰り返して開発を進めます。
そのうち RSpec についてもう少し説明しようと思います。
最終的なサンプルコード
sample_project/spec/spec_helper.rb
# encoding: utf-8 require "rubygems" require 'test/unit' require "spec" $LOAD_PATH << File.expand_path(File.join('..', 'lib'), File.dirname(__FILE__))
sample_project/spec/sample_spec.rb
# -*- coding: utf-8 -*- require File.expand_path(File.join('.', 'spec_helper'), File.dirname(__FILE__)) require 'sample' # for lib/sample.rb describe Sample, "When mix two numbers," do before(:each) do @sample = Sample.new end it "should calculate as +" do @sample.mix(1, 1).should == 2 @sample.mix(100, 11).should == 111 @sample.mix(10, -109).should == -99 end end
sample_project/lib/sample.rb
class Sample def mix(item1, item2) return item1 + item2 end end
Related posts:
- [JRuby on Rails on GAE/J] rubygems を jar ファイルの中にまとめる GAE/J で Rails アプリを開発するとき、GAE/J 上にアップロードできるファイル数の制限の関係から、 なんとかしてファイル数を減らしたくなります。 そこで、有効なのが、使用する rubygems を jar...
- [Rails] ActiveRecord で DateTime を使う ActiveRecord の :datetime は ruby Time class に対応してるんだけど、 ruby の...
Related posts brought to you by Yet Another Related Posts Plugin.


English
Japanese
記事
コメント