フィルタリング
RSpec.configure
に渡されるブロックで定義された before
、after
、および around
フックは、フィルタとしてメタデータを使用して特定の例やグループに制約を加えることができます。
(RSpec.configure do |c|
c.before(:example, :type => :model) do
end
end
RSpec.describe "something", :type => :model do
end
フィルタされた :context
フックは、一致するメタデータを持つ個々の例にも適用されることに注意してください。実際には、すべての例には単一の例グループがあり、その中には単一の例だけが含まれています(Rubyのシングルトンクラスに類似しています)。
また、シンボルのみを使用してメタデータを指定することもできます。
任意のメタデータを使用して before(:example)
フックをフィルタリングする
次の内容で "filter_before_example_hooks_spec.rb" という名前のファイルがあるとします:
RSpec.configure do |config|
config.before(:example, :foo => :bar) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without matching metadata" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "runs the hook for an example with matching metadata", :foo => :bar do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata", :foo => :bar do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
rspec filter_before_example_hooks_spec.rb
を実行すると
すべての例がパスするはずです。
任意のメタデータを使用して after(:example)
フックをフィルタリングする
次の内容で "filter_after_example_hooks_spec.rb" という名前のファイルがあるとします:
RSpec.configure do |config|
config.after(:example, :foo => :bar) do
raise "boom!"
end
end
RSpec.describe "a filtered after :example hook" do
describe "group without matching metadata" do
it "does not run the hook" do
# should pass
end
it "runs the hook for an example with matching metadata", :foo => :bar do
# should fail
end
end
describe "group with matching metadata", :foo => :bar do
it "runs the hook" do
# should fail
end
end
end
rspec filter_after_example_hooks_spec.rb
を実行すると
出力には "3 examples, 2 failures" が含まれるはずです。
任意のメタデータを使用して around(:example)
フックをフィルタリングする
次の内容で "filter_around_example_hooks_spec.rb" という名前のファイルがあるとします:
RSpec.configure do |config|
config.around(:example, :foo => :bar) do |example|
order << :before_around_example_foo_bar
example.run
expect(order).to eq([:before_around_example_foo_bar, :example])
end
end
RSpec.describe "a filtered around(:example) hook" do
let(:order) { [] }
describe "a group without matching metadata" do
it "does not run the hook" do
expect(order).to be_empty
end
it "runs the hook for an example with matching metadata", :foo => :bar do
expect(order).to eq([:before_around_example_foo_bar])
order << :example
end
end
describe "a group with matching metadata", :foo => :bar do
it "runs the hook for an example with matching metadata", :foo => :bar do
expect(order).to eq([:before_around_example_foo_bar])
order << :example
end
end
end
rspec filter_around_example_hooks_spec.rb
を実行すると
すべての例がパスするはずです。
任意のメタデータを使用して before(:context)
フックをフィルタリングする
次の内容で "filter_before_context_hooks_spec.rb" という名前のファイルがあるとします:
RSpec.configure do |config|
config.before(:context, :foo => :bar) { @hook = :before_context_foo_bar }
end
RSpec.describe "a filtered before(:context) hook" do
describe "a group without matching metadata" do
it "does not run the hook" do
expect(@hook).to be_nil
end
it "runs the hook for a single example with matching metadata", :foo => :bar do
expect(@hook).to eq(:before_context_foo_bar)
end
describe "a nested subgroup with matching metadata", :foo => :bar do
it "runs the hook" do
expect(@hook).to eq(:before_context_foo_bar)
end
end
end
describe "a group with matching metadata", :foo => :bar do
it "runs the hook" do
expect(@hook).to eq(:before_context_foo_bar)
end
describe "a nested subgroup" do
it "runs the hook" do
expect(@hook).to eq(:before_context_foo_bar)
end
end
end
end
rspec filter_before_context_hooks_spec.rb
を実行すると
すべての例がパスするはずです。
任意のメタデータを使用して after(:context)
フックをフィルタリングする
次の内容で "filter_after_context_hooks_spec.rb" という名前のファイルがあるとします:
example_msgs = []
RSpec.configure do |config|
config.after(:context, :foo => :bar) do
puts "after :context"
end
end
RSpec.describe "a filtered after(:context) hook" do
describe "a group without matching metadata" do
it "does not run the hook" do
puts "unfiltered"
end
it "runs the hook for a single example with matching metadata", :foo => :bar do
puts "filtered 1"
end
end
describe "a group with matching metadata", :foo => :bar do
it "runs the hook" do
puts "filtered 2"
end
end
describe "another group without matching metadata" do
describe "a nested subgroup with matching metadata", :foo => :bar do
it "runs the hook" do
puts "filtered 3"
end
end
end
end
rspec --format progress filter_after_context_hooks_spec.rb --order defined
を実行すると
すべての例がパスするはずです。
また、出力には次の内容が含まれるはずです:
unfiltered
.filtered 1
after :context
.filtered 2
.after :context
filtered 3
.after :context
シンボルをメタデータとして使用する
次 の内容で "less_verbose_metadata_filter.rb" という名前のファイルがあるとします:
RSpec.configure do |c|
c.before(:example, :before_example) { puts "before example" }
c.after(:example, :after_example) { puts "after example" }
c.around(:example, :around_example) do |example|
puts "around example (before)"
example.run
puts "around example (after)"
end
c.before(:context, :before_context) { puts "before context" }
c.after(:context, :after_context) { puts "after context" }
end
RSpec.describe "group 1", :before_context, :after_context do
it("") { puts "example 1" }
it("", :before_example) { puts "example 2" }
it("", :after_example) { puts "example 3" }
it("", :around_example) { puts "example 4" }
end
When I run rspec --format progress less_verbose_metadata_filter.rb
Then the examples should all pass
And the output should contain:
before context
example 1
.before example
example 2
.example 3
after example
.around example (before)
example 4
around example (after)
.after context
シンボルを使用してフックをフィルタリングする
Given a file named "filter_example_hooks_with_symbol_spec.rb" with:
RSpec.configure do |config|
config.before(:example, :foo) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without a matching metadata key" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "does not run the hook for an example with metadata hash containing the key with a falsey value", :foo => nil do
expect(invoked_hooks).to be_empty
end
it "runs the hook for an example with metadata hash containing the key with a truthy value", :foo => :bar do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
it "runs the hook for an example with only the key defined", :foo do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata key", :foo do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
When I run rspec filter_example_hooks_with_symbol_spec.rb
Then the examples should all pass.
ハッシュを使用してフックをフィルタリングする
Given a file named "filter_example_hooks_with_hash_spec.rb" with:
RSpec.configure do |config|
config.before(:example, :foo => { :bar => :baz, :slow => true }) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without matching metadata" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "does not run the hook for an example if only part of the filter matches", :foo => { :bar => :baz } do
expect(invoked_hooks).to be_empty
end
it "runs the hook for an example if the metadata contains all key value pairs from the filter", :foo => { :bar => :baz, :slow => true, :extra => :pair } do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata", :foo => { :bar => :baz, :slow => true } do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
When I run rspec filter_example_hooks_with_hash_spec.rb
Then the examples should all pass.
Procを使用してフックをフィルタリングする
Given a file named "filter_example_hooks_with_proc_spec.rb" with:
RSpec.configure do |config|
config.before(:example, :foo => Proc.new { |value| value.is_a?(String) } ) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without matching metadata" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "does not run the hook if the proc returns false", :foo => :bar do
expect(invoked_hooks).to be_empty
end
it "runs the hook if the proc returns true", :foo => 'bar' do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata", :foo => 'bar' do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
When I run rspec filter_example_hooks_with_proc_spec.rb
Then the examples should all pass.
正規表現を使用してフックをフィルタリングする
Given a file named "filter_example_hooks_with_regexp_spec.rb" with:
RSpec.configure do |config|
config.before(:example, :foo => /bar/ ) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without matching metadata" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "does not run the hook if the value does not match", :foo => 'baz' do
expect(invoked_hooks).to be_empty
end
it "runs the hook if the value matches", :foo => 'bar' do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata", :foo => 'bar' do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
When I run rspec filter_example_hooks_with_regexp_spec.rb
Then the examples should all pass.
文字列比較を使用してフックをフィルタリングする
Given a file named "filter_example_hooks_with_strcmp_spec.rb" with:
RSpec.configure do |config|
config.before(:example, :foo => :bar ) do
invoked_hooks << :before_example_foo_bar
end
end
RSpec.describe "a filtered before :example hook" do
let(:invoked_hooks) { [] }
describe "group without matching metadata" do
it "does not run the hook" do
expect(invoked_hooks).to be_empty
end
it "does not run the hook if the coerced values do not match", :foo => 'baz' do
expect(invoked_hooks).to be_empty
end
it "runs the hook if the coerced values match", :foo => 'bar' do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
describe "group with matching metadata", :foo => 'bar' do
it "runs the hook" do
expect(invoked_hooks).to eq([:before_example_foo_bar])
end
end
end
When I run rspec filter_example_hooks_with_strcmp_spec.rb
Then the examples should all pass.