初心者がRailsを勉強するブログ

Railsを0からお勉強するブログです。

初めてのRSpec

今回は基本的なRSpecの使い方を見ていこうと思います。

まず、RSpecが何なのかを見てみましょう。
この記事がわかりやすいです。

一言で言うと、テストを標準よりいい感じにかけるDSLです。
この記事は使い方を見ていくので、標準のTest::Unitよりどういい感じなのかはここでは割愛します。
興味が湧いたらぜひ標準のTest::Unitと比較してみてください。

さっそくRSpecのコードを書いてみましょう。
変数helloの中身が"Hello, World!であることをテストするコードを書いてみます。
テスト駆動開発(TDD)を意識して、テストを先に書きます。

コードを書く前に、RSpecが動くようにしましょう。

$ rspec --init

これで、カレントディレクトリにspecというディレクトリが出来ます。
そして、specディレクトリの中にはspec_helper.rbがあります。
とりあえず、このspec_helperは無視して簡単なテストを書きましょう。

specディレクトリの中にRSpecのコードを置きます。ファイル名は*_spec.rbのように、拡張子の前に_specをつけましょう。
それでは、スペックファイルを編集します。ファイル名はhello_spec.rbでいきます。

$ vim spec/hello_spec.rb

今回のテスト内容は、変数helloの内容が"Hello, World!"であるかテストすることです。
とりあえず、無邪気にRubyのコードで書いてみます。

describe "超簡単なRSpecコード" do
  hello == "Hello, World!"
end

テストが書けました!実行してみます。

$ rspec spec

こんなんが出てきました。

undefined local variable or method `hello' for main:Object (NameError)

helloなんて変数を書いてないんだからNameErrorが出るのは当然ですね。
では、このテストに通るようにコードを書きましょう。

$ vim spec/hello_spec.rb

変数helloに"Hello, World!"を入れます。
下のコードをhello_spec.rb先頭に追加してください。

hello = "Hello, World!"

これでテストに通るはずです。また実行してみましょう。

$ rspec spec

無事通りました!
ですが、このコードはRSpecのメソッドを使っていないため、残念な感じです。
テストの部分をRSpecのメソッドを使ったものに書き換えます。

describe "超簡単なRSpecコード" do
  it "変数helloの内容はHello, World!"  do
    expect(@hello).to eq "Hello, World!"
  end
end

itメソッドは引数にブロックを取ります。
テストのコードをブロック内に記述します。

なんかそれっぽくなりました。RSpecはすごく英語っぽくて読みやすいですよね。

次に、変数helloに値を入れるところもいけてません。
別ファイルにするか、beforeブロックに入れたいです。

今回は一行しかないので、beforeブロックに入れましょう。
以下のコードをdescribeブロックの先頭に入れます。

before { @hello = "Hello, World!" }

beforeブロックの中身はテスト実行前に実行されます。
helloの前の@はhelloがローカル変数のままだと、helloがbeforeブロック内でしか生きられないからつけました。

書き換えた後のhello_spec.rbはこんな感じ。

describe "超簡単なRSpecコード" do
  # テストをする前に変数helloに値をセットする
  before { @hello = "Hello, World!" }

  # テストコード
  it "変数helloの内容はHello, World!" do
    expect(@hello).to eq "Hello, World!"
  end
end

かなりそれっぽくなりました。
このコードを実行すれば、テストには通ります。
こんな感じに。

f:id:carmelokarimero:20140222232923p:plain

ただ、この実行結果って情報量が少なくありませんか?
せっかくdescribeとitの後に文字列を書いたのに、表示されないなんてもったいないです。

というわけで、書いた文字列が表示されるようにしましょう。
.rspecを書き換えます。

$ vim .rspec

--formatの後ろのprogressをdocに書き換えます。
これで実行してみましょう。

f:id:carmelokarimero:20140222233015p:plain

コード内に入力した文字列が表示されました!
これで見やすくなりました。

ちょっとやりたいことがあるので、変数fooの中が'bar'か判定するコードを追加します。
hello_rspec.rbを書き換えます。

describe '超簡単なRSpecのコード' do
  context 'helloのテスト' do
    before { @hello = "Hello, World!"}
    
    it '変数helloの内容はHello, World!' do
      expect(@hello).to eq 'Hello, World!'
    end
  end

  context 'fooのテスト' do
    it '変数fooの内容はbar' do
      expect(@foo).to eq "bar"
    end
  end
end

複数のテストを書くときに、contextでブロックを分けるのをやりたかったのでした。
さっそく、テストに落ちるために実行してみましょう。

無事、テストに落ちましたか?
今回は、RSpecのメソッドで書いたので、NameErrorではなくまっとうにfailureが出たはずです。
こんな感じ。

f:id:carmelokarimero:20140222233256p:plain

テストに通って、今回は終わりにしましょう。
以下のコードをfooのコンテキストの先頭に書きます。

before { @foo = "bar" }

書けたら実行してみましょう。

f:id:carmelokarimero:20140222233408p:plain

無事に通りました。

まずは基本的なRSpecの使い方を見ました。
次はRailsでのRSpecを見て行きましょう。