ちょっと前に話題になったRSpecのスライドがステキだったよね。でもRSpecはまだまだ底知れない気がするので自分でもいろいろと調べてみようと思った次第。
まずはrspec-core(2.5.1)/features/example_groups/shared_example_group.featureを参考にshared example groupについて調べてみたよ。
例1:テストを共有できる
require "set" shared_examples_for 'a collection' do subject { described_class.new [7, 2, 4] } its(:size) { should eq 3 } it { should include 7 } it { should_not include 9 } end describe Array do it_behaves_like 'a collection' end describe Set do it_behaves_like 'a collection' end
% rspec -cfs shared_example_group_1.rb Array behaves like a collection should include 7 should not include 9 size should == 3 Set behaves like a collection should include 7 should not include 9 size should == 3
まぁ単純に使うとこうなる。同じテストをあちこちに書いてたらDRYに反するのでまとめれると嬉しいよね。ここまでは知ってた。described_classも何かと使えそうな気がする。
例2:ブロックを渡せる
require "set" shared_examples_for 'a collection object' do subject { collection << 1 << 2 } its(:to_a) { should eq [1,2] } end describe Array do it_should_behave_like 'a collection object' do let(:collection) { Array.new } end end describe Set do it_should_behave_like 'a collection object' do let(:collection) { Set.new } end end
% rspec -cfs shared_example_group_2.rb Array it should behave like a collection object to_a should == [1, 2] Set it should behave like a collection object to_a should == [1, 2] Finished in 0.00189 seconds 2 examples, 0 failures
ブロックを渡すとそれぞれのサンプルでいい按配で使ってくれるみたいなのでこれは便利そう。
例3:引数を渡せる
shared_examples_for 'a measurable object' do |measurement, measurement_methods| measurement_methods.each do |measurement_method| its(measurement_method) { should == measurement } end end describe Array, 'with 3 items' do subject { [1, 2, 3] } it_should_behave_like 'a measurable object', 3, [:size, :length] end describe String, 'of 6 characters' do subject { 'FooBar' } it_should_behave_like 'a measurable object', 6, [:size, :length] end
% rspec -cfs shared_example_group_3.rb Array with 3 items it should behave like a measurable object size should == 3 length should == 3 String of 6 characters it should behave like a measurable object size should == 6 length should == 6 Finished in 0.00215 seconds 4 examples, 0 failures
若干ややこしいし、使いどころが難しいような気がするが、上手く使えればシンプルにまとめられる場面はあるように思う。
例4:it_should_behave_likeじゃなくできる
RSpec.configure do |c| c.alias_it_should_behave_like_to :it_has_behavior, 'has behavior:' end shared_examples_for 'sortability' do it { should respond_to :<=> } end describe String do it_has_behavior 'sortability' do subject { 'sample string' } end end
% rspec -cfs shared_example_group_4.rb String has behavior: sortability should respond to #<=> Finished in 0.00275 seconds 1 example, 0 failures
it_should_behave_likeって長すぎるしイマイチよくわからないよね。ってときはなんとエイリアスできるようだ。出力メッセージも変えれる。
といったところでやっぱりRSpecはまだまだ掘れそうな雰囲気です。いきなりletとかitsとかimplicit subjectとか使いまくってるんで、最初にshared example groupもってきたのは失敗な気がするけどまぁいいか。その辺についてはあとで書く。
続く。