RSpec 3の重要な変更 - 有頂天Ruby
こちらを見ながら手元のテストをRSpec3に対応していました。
一時の慣れで済むのでしょうが、色々変わって大変です。
リンク先メモ
メジャーな修正内容は省略。
フックスコープのための新しい名前: :example と :context
each / all / suite
c.before(:each) { } # 全てのテストスイート中のそれぞれのexampleの前に実行される c.before(:all) { } # それぞれのトップレベルのグループの最初のexampleの前に実行される c.before(:suite) { } # 全てのspecファイルがロードされたあと、最初のspecが実行される前に一度だけ実行される
each => example
all => context
DSLメソッドがexampleを引数として渡す
exampleなんて知らなかった。色々取得できます。
#RSpec2 describe MyClass do before(:each) { puts example.metadata } end #RSpec3 before(:example) { |ex| puts ex.metadata } let(:example_description) { |ex| ex.description } it 'exampleにアクセス' do |ex| # exを使う end
example groupの新しいエイリアス: xdescribe, xcontext, fdescribe, fcontext
xつけるとskip、fつけるとfocus
ワンライナーのための新しいAPI: is_expected
# rspec2 it { should allow_mass_assignment_of(:title) } # rspec3 it { is_expected.to allow_mass_assignment_of(:title) }
should_not は is_expected.not_to
新しいoutputマッチャー
以前は、こういうのを用意しておいて
# spec_helper.rb def capture(stream) begin stream = stream.to_s eval "$#{stream} = StringIO.new" yield result = eval("$#{stream}").string ensure eval("$#{stream} = #{stream.upcase}") end result end
stdoutをすり替えるようなことをしていたのですが
# RSpec2 it 'display with expanding name column' do expect(capture(:stdout) { @executor.search('long_pod_name') }).to eq <<-'EOS'.unindent |Name(Ver) Score Star Fork |--------------------------------------------- ------ ----- ----- |AFNetworking (2.2.3) 28241 11941 3260 |ACECoreDataNetworkTableViewController (0.0.2) 2 2 0 |AKANetworkLogging (0.1.0) 1 1 0 EOS end
似たようなものがデフォルトで用意され、こういう書き方ができるようになりました。
# RSpec3 it 'display with expanding name column' do res = <<-'EOS'.unindent |Name(Ver) Score Star Fork |--------------------------------------------- ------ ----- ----- |AFNetworking (2.2.3) 28241 11941 3260 |ACECoreDataNetworkTableViewController (0.0.2) 2 2 0 |AKANetworkLogging (0.1.0) 1 1 0 EOS expect { @executor.search('sqlite') }.to output(res).to_stdout end
Booleanマッチャーの名前がかわりました
be_truthyとbe_false (be_true/be_falseと同じように読めるが、ほんとにtrue/falseのときしか通らない)
他やってて気づいたこと
its
its がrspec-its に切り出されました。
gem 'rspec-its'
して
require 'rspec/its'
すればok。
subjectと併用時のshould
(itsの例ですがitでも同じ)
これはwarningの対象外です。これをexpectで書くとなんとまぁ残念なことになるのですがshouldと書いても大丈夫なようです。
subject { @agent } its(:proxy_addr) { should eq '192.168.1.99' } its(:proxy_user) { should eq 'proxy_user' } its(:proxy_pass) { should eq 'proxy_pass' } its(:proxy_port) { should eq 9999 }