学んだことをなぐり書き


ファイルの命名規則

基本的には「テストしたいクラス名のsnake case(小文字とアンダーバーで単語を繋げていくやつ)_spec.rb」の形にする。

generate

基本的に通常の generate コマンドの先頭に rspec_ を付ける。
  • script/generate rspec_scaffold list name:string
  • script/generate rspec_model page item:references
  • script/generate rspec_controller wiki new show edit list

describe, it

基本的に RSpec でテストをする場合は、describe と it のメソッドを使って行う。

describe テストするクラス名, "テスト時の状態の説明" do
  it "テスト内容(なっててほしい状態の説明)" do
  end
end

の形をとる。クラス名は書かなくてもエラーにはならない。

テスト時の状態の説明は英語では「when 内容」のような書き方をする。
テスト内容はの説明は英語では「should be 内容」のような書き方をする。

describe "こういう時に(when ...)" do
  it "こうなってて欲しい(should be ...)" do
    # テストの処理
  end
end

should, should_not

it のメソッドの中で正しい条件をチェックする時に使う(アサートのようなもの)
Objectクラスを拡張して全てのクラスのメンバ関数にshouldなどのメソッドの追加を行っている。

puts Object.instance_methods(true)

でObjectの全てのメソッドが表示すると、どんなメソッドが追加されているのか分かる。
通常のObjectのメソッドと差分をとろうと思ったんだけどめんどくさいので止めた^q^

使い方としては 変数.should == 値 のような形になる
!= のような否定演算子は用意されておらず。should_not メソッドを使う。

describe Fixnum, "が10の時" do
  it "10は10なのだろうか?(ちょっと何いってるかわかんないっすね。まぁ例なので)" do
    10.should == 10
  end

  it "10は10ではないのだろうか?(ちょっとなry)" do
    10.should_not == 10
  end
end

上記を実行すると当然なのだが 10.should_not == 10 のほうでエラーがでる。
実行する時のオプションで -fs と -c を追加すると見やすくなる。

spec -fs -c .rb

Fixnum が10の時
- 10は10なのだろうか?(ちょっと何いってるかわかんないっすね。まぁ例なので)
- 10は10ではないのだろうか?(ちょっとなry) (FAILED - 1)

1)
'Fixnum が10の時 10は10ではないのだろうか?(ちょっとなry)' FAILED
expected not: == 10,
         got:    10
./.rb:8:

Finished in 0.017075 seconds

2 examples, 1 failure

should_receive

describe "メソッドが呼ばれたかを確認したい場合" do
  it 'should_receive を使用する' do
    obj = Class.new do
      def check; end
      def say; check; end
    end.new
    obj.should_receive(:say)

    # コメントにすると check は呼ばれないのでエラーになる
    obj.say
  end
end

before, after

テストを行う前に初期化をしておきたい場合(データベースの接続や、クラスの初期化、値の代入など)は before メソッド内に記述する。

テストが終わったのに行いたい処理は after メソッド内に記述する。

before, after には :each か :all の引数を取る。
何も指定しない場合は :each になる。

:each は it メソッド の前後に呼び出される。
:all は describe メソッド の前後に呼び出される。

describe "before と after の使い方" do
  before do
    puts "before default"
  end

  before(:all) do
    puts "before all"
  end

  before(:each) do
    puts "before each"
  end

  after do
    puts "after default"
  end

  after(:all) do
    puts "after all"
  end

  after(:each) do
    puts "after each"
  end

  it "テスト1" do
    puts "テスト1"
  end

  it "テスト2" do
    puts "テスト2"
  end

  it "テスト3" do
    puts "テスト3"
  end
end

be_XXX, have_XXX

be_XXX というメソッドは XXX? メソッドに変換される
be_empty の場合 empty? メソッドが呼ばれる

have_XXX というメソッドは has_XXX? メソッドに変換される
have_key の場合 has_key? メソッドが呼ばれる

describe Hash, "で be_XXX, have_XXX を試す" do
  before do
    @hash = {:a => "A"}
  end

  it "be_empty を試す" do
    @hash.should_not be_empty
  end

  it "have_key を試す" do
    @hash.should have_key(:a)
  end
end

自分で適当なクラスを作ってみて試してみると分かりやすいかも

class A
  def hoge?
    puts "call A::hoge?"
    true
  end
  def has_moke?
    puts "call A::has_moke?"
    true
  end
end

describe A, "のテスト" do
  it "be_hoge を呼んでみる" do
    A.new.should be_hoge
  end

  it "have_moke を呼んでみる" do
    A.new.should have_moke
  end
end

その他のマッチャについての詳細はRDocにあるらしい

violated, pending

violated はテストを失敗状態にしておきたいときに使う。(たぶん)
pending は忙しいから後でテスト書こうみたいな時の目印として使う。(たぶん)


describe "violated, pending を試す。" do
  it "violated は必ずテストを失敗させるメソッド" do
    violated("まだここを通すわけにはいかないな(キリッ")
  end

  it "pending は一時テストを保留させるメソッド" do
    pending("ちょっと一休みしていこかw")
  end
end

また it にブロックを与えない場合も pending(保留)扱いになる。
どういうテストが欲しいか最初にリストを作るときに便利そう。

pending(メッセージ) { 保留したい処理 } の場合は、ブロックの中の処理のみスルーする。
後で書けばいいやというときに使うんだろうと思う。
でもpendingをブロックで囲んだ場合は failure(失敗) 評価になるっぽい。

describe "色んなpending(保留)処理" do
  it "ブロックを与えないと保留扱い"

  it "pending メソッドの後ブロックで囲むとそこだけ保留扱い" do
    pending("ブロックのpendingの場合は failure 扱いになるっぽい") do
      # ここだけ評価しない
    end
  end

  it "pending メソッドだけをコールするとその後の処理は全て保留" do
    true.should be_true
    pending("これ以降評価しないよん")
    true.should be_false
  end
end

raise_error - 例外をテストする

describe Object do
  it 'raise_error' do
    lambda {
      raise RuntimeError
    }.should raise_error(RuntimeError)
  end
end

メンバーのみ編集できます