読者です 読者をやめる 読者になる 読者になる

実践Rails学習ノート#2【RSpecテスト】

前回に引き続き勉強したところをメモしながらやっていこうと思います。

Gemfileにrspecを追加して、

# Gemfile
group :development, :test do
  gem 'rspec-rails', '~> 3.0'
end

rspecは以下でインストールできます。

$ bundle exec rails generate rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb

肩慣らしててきな

最初に、RSpecに慣れるためにめちゃくちゃ簡単なテストを書いてみます。

# spec/experiments/string_spec.rb
require 'spec_helper'

describe String do
  describe '#<<' do
    example '文字の追加' do
      s = "ABC"
      s << "D"
      expect(s.size).to eq(4)
    end
  end
end

experimentsはRubyRailsの仕様に関するテストをおいとくディレクトリとしてます。

そしてこれを実行してみると、以下のようになりました。

▶ bin/rspec spec/experiments/string_spec.rb
.

Finished in 0.00234 seconds (files took 0.45125 seconds to load)
1 example, 0 failures

うん、成功してますね。

また全部一括でやっちゃいときには各specファイルをいちいち指定しなくても以下で実行できます。

▶ bin/rspec spec

BDD (Behavior Driven Development)

なぜ RSpec はそれをエグザンプルと呼ぶのでしょうか。それは、ビヘイビア駆動開発では、テス トコードによってソフトウェアの仕様(specification)が定義される、と考えるからです。

ということでRSpecはアプリケーションの振る舞いをテストします。これは、アプリケーションでは、実際のコードが仕様を定義するという原則に従っているってことですね。

テストを失敗させてみる

さっきのspecファイルにexampleを追加してわざとテストを落としてみます。

require 'spec_helper'

describe String do
  describe '#<<' do
    example '文字の追加' do
      s = "ABC"
      s << "D"
      expect(s.size).to eq(4)
    end

    example 'nilの追加' do
      s = "ABC"
      s << nil
      expect(s.size).to eq(4)
    end
  end
end

結果は以下のようになりました。

▶ bin/rspec spec
.F

Failures:

  1) String#<< nilの追加
     Failure/Error: s << nil
     TypeError:
       no implicit conversion of nil into String
     # ./spec/experiments/string_spec.rb:13:in `block (3 levels) in <top (required)>'
     # -e:1:in `<main>'

Finished in 0.00241 seconds (files took 0.20153 seconds to load)
2 examples, 1 failure

Failed examples:

rspec ./spec/experiments/string_spec.rb:11 # String#<< nilの追加

最初の行の.は成功を表していて、Fが失敗を表しています。ただしテストの実行順番は必ずしも順番というわけではないらしいです。

さて、テストが失敗したら、その原因を突き止めて編集->bin/rspec specを繰り返すことになると思うのですが、すぐにできないみたいなときには以下のように一時保留にすることができます。

    example 'nilの追加' do
      pending('調査中...')
      s = "ABC"
      s << nil
      expect(s.size).to eq(4)
    end

pendingって書かなくてもexamplexexampleにするのでもokです。結果は以下。

▶ bin/rspec spec
.*

Pending:
  String#<< nilの追加
    # 調査中...
    # ./spec/experiments/string_spec.rb:11

Finished in 0.00249 seconds (files took 0.18274 seconds to load)
2 examples, 0 failures, 1 pending

*でまだ未解決ということが分かると思います。Fと違ってきちんと失敗を認識して調査中/作業中ということが分かるのがいいですね。

expectメソッドと抹茶

expectは、以下のように使います。

expect(T).to M

Tがターゲットで、Mがマッチャーです。たとえばこんな感じ。

expect(s.size).to eq(4)

ひとまずこんな感じでRSpecの超入門おわりということで!

テストはもっと詳しく後でやります!!

  • ノート#3

実践Rails学習ノート#3【Viewで基礎を作る】 - 凸ろぐ