问题
I'm trying to architect my tests in such a way so I can run certain context blocks by themselves, but also need to further enforce nested tags in individual it blocks. Something like this:
context 'outer context', :outer_tag do
it 'inner it', :tag1 do
expect(1).to eq(1)
end
it 'inner it 2', :tag2 do
expect(2).to eq(2)
end
end
and I want to run something along the lines of:
rspec --tag outer-tag --tag tag1
in the hopes that it will only run tests within the context tagged with :outer-tag that are themselves tagged with :tag1
Is there a way to get this behavior? Currently this seems to operate as an 'or' when I guess I am looking for it to operate as more of an 'and'.
thanks!
回答1:
You can do something like this:
RSpec.describe 'Something' do
context 'outer context', :outer_tag do
it 'inner one', :tag1, outer_tag: 'tag1' do
expect(1).to eq(1)
end
it 'inner two', :tag2, outer_tag: 'tag2' do
expect(2).to eq(2)
end
end
context 'another context', :different_tag do
it 'inner three', :tag2, different_tag: 'tag2' do
expect(3).to eq(3)
end
end
end
and then running:
rspec example.rb --tag 'outer_tag'
# => Something
# outer context
# inner one
# inner two
rspec example.rb --tag 'outer_tag:tag2'
# => Something
# outer context
# inner two
rspec example.rb --tag tag2
# => Something
# outer context
# inner two
# another context
# inner three
This starts to get weird when you need multiple levels though:
context 'third context', :final_tag do
context 'inside third', :inner_third, final_tag: 'inner_third' do
it 'inner four', :inner_four, inner_third: 'inner_four', final_tag: 'inner_third:inner_four' do
expect(4).to eq(4)
end
end
end
rspec example.rb --tag 'final_tag:inner_third:inner_four'
rspec example.rb --tag 'inner_third:inner_four'
rspec example.rb --tag inner_four
# All run
# => Something
# third context
# inside third
# inner four
Works, but is extremely verbose.
And because of the way rspec handles tags on the command line (hashes), it can lead to some unexpected stuff trying to combine them:
rspec example.rb --tag outer_tag --tag ~'outer_tag:tag2'
# Run options: exclude {:outer_tag=>"tag2"}
# => Something
# outer context
# inner one
# another context # <- nothing in this context was expected to run
# inner three (FAILED - 1)
This way works though:
rspec example.rb --tag outer_tag --tag ~tag2
# => Something
# outer context
# inner one
回答2:
You can also use RSpec' exclusion filter to run all your :outer_tag
tests, except those having the :tag1
spec.
RSpec.configure do |config|
config.filter_run :outer_tag
config.filter_run_excluding :tag1
end
Only the tests with :tag2
is run:
> rspec -fd tag_spec.rb
Run options:
include {:outer_tag=>true}
exclude {:tag1=>true}
outer context
inner it 2
Finished in 0.00326 seconds (files took 1.07 seconds to load)
1 example, 0 failures
You can use environment variables so as not to modify your code to just to run a subset of the tests.
来源:https://stackoverflow.com/questions/46245768/running-nested-tags-in-rspec