TL;DR Avoid before(:context)
(formerly before(:all)
), use before(:example)
(formerly before(:each)
) instead.
If you do use before(:context)
, you need to know what you are doing and take care of any cleanup yourself.
Why?
Understand this:
-
before(:context)
is run when thecontext
/describe
block begins, -
before(:context)
is run outside of transactions, so data created here will bleed into other specs -
before(:example)
is run before each spec inside it,
Generally, you'll want a clean setup for each spec so that they are independent of other specs in the same context.
Example
Consider this spec:
describe User, 'something' do
before :context do
@user = User.make
end
it 'should so something' do
# ...
end
it 'should so something else' do
# ...
end
end
If you do that, @user
will not be re-created for each test. Obviously, this has significant downsides, mostly that changes of one test on that record will bleed into the next one. \
Also, when using DatabaseCleaner
with the :deletion
strategy, the record will be gone after the first spec.
Doing it right
before(:example)
is the right choice in most cases. So, for the above example we say the following and all is well.
describe User, 'something' do
before :example do
@user = User.make
end
# ...
end
Furthermore, you will probably run into trouble with your RSpec configuration block that does things in config.before(:example)
, as this will also be run after your individual spec's before(:context)
block did things and might revert changes.
Always use before(:example)
unless you are totally sure of the impact your before(:context)
block has.