From 1b3ac4baab178dbed817b89e604bedd8bbb31217 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Thu, 4 Jul 2024 17:45:21 +1200 Subject: [PATCH 01/10] Compromise solution to #2773 --- lib/rspec/rails/adapters.rb | 39 +++++++++ .../rails/example/rails_example_group.rb | 2 +- .../rails/example/rails_example_group_spec.rb | 80 +++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) diff --git a/lib/rspec/rails/adapters.rb b/lib/rspec/rails/adapters.rb index 74bee1c85..689f897eb 100644 --- a/lib/rspec/rails/adapters.rb +++ b/lib/rspec/rails/adapters.rb @@ -136,6 +136,45 @@ def method_name end end + # @private + # + # ActiveSupport::CurrentAttributes::TestHelper uses both before-setup and + # after-teardown hooks to clear attributes. These are run in an awkward + # order relative to RSpec hooks. Client suite-configured "around each" + # hooks run first, the attribute reset hooks next, and contexts or examples + # (along with whatever their defined hooks might be) run last. Consequently + # a suite which sets up around-each-example attributes could fail, because + # the attributes would have been reset by time tests actually run. + # + # Reworking with "before" rather than "around" hooks sidesteps the problem. + # Unfortunately, "executes via a block to clean up after itself" cases such + # as with "ActsAsTenant.without_tenant ..." make such a rework either hard + # or impossible. Besides, even realising that you may need to do this can + # take some significant debugging effort and insight. + # + # The compromise is to use "half" of what ActiveSupport does - just add the + # after-hook. Attributes are now only reset after examples run, but still + # before a suite-wide "around" hook's call to "example.run()" returns. If a + # test suite depended upon current attribute data still being set *after* + # examples within its suite-wide "around" hook, it would fail. This is + # unlikely; it's overwhelmingly common to just *set up* data before a test, + # and usually the only things you're doing afterwards are cleanup. + # + # Include this module to reset under the above compromise, instead of + # including ActiveSupport::CurrentAttributes::TestHelper. + # + module ActiveSupportCurrentAttributesAdapter + extend ActiveSupport::Concern + + included do + def after_teardown + puts "AFTER TEARDOWN" + super + ActiveSupport::CurrentAttributes.reset_all + end + end + end + # @private module MinitestAssertionAdapter extend ActiveSupport::Concern diff --git a/lib/rspec/rails/example/rails_example_group.rb b/lib/rspec/rails/example/rails_example_group.rb index ed343de35..196666d8b 100644 --- a/lib/rspec/rails/example/rails_example_group.rb +++ b/lib/rspec/rails/example/rails_example_group.rb @@ -19,7 +19,7 @@ module RailsExampleGroup include RSpec::Rails::FixtureSupport if ::Rails::VERSION::MAJOR >= 7 include RSpec::Rails::TaggedLoggingAdapter - include ActiveSupport::CurrentAttributes::TestHelper + include RSpec::Rails::ActiveSupportCurrentAttributesAdapter include ActiveSupport::ExecutionContext::TestHelper end end diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 7dbe13788..2dc701d8c 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -56,5 +56,85 @@ class CurrentSample < ActiveSupport::CurrentAttributes group.run(failure_reporter) ? true : failure_reporter.exceptions ).to be true end + + context 'with suite-level around-example hooks configured', if: ::Rails::VERSION::MAJOR >= 7 do + let(:uniquely_identifiable_metadata) do + { configured_around_example_hook: true } + end + + class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes + attribute :request_id + end + + # We have to modify the suite's around-each in RSpec.config, but don't + # want to pollute other tests with this (whether or not it is harmless + # to do so). There being no public API to read or remove hooks, instead + # it's necessary use some private APIs to be able to delete the added + # hook via 'ensure'. + # + around :each do | example | + + # Client code might legitimately want to wrap examples to ensure + # all-conditions tidy-up, e.g. "ActsAsTenant.without_tenant do...", + # wherein an "around" hook is the only available solution, often used + # in the overall suite via "config.around". Tests would not expect + # anything set in CurrentAttributes here to suddenly be reset by the + # time their actual tests, or their test hooks ran. + # + RSpec.configure do | config | + config.around(:each, uniquely_identifiable_metadata()) do | example | + CurrentAttrsBetweenHooks.request_id = '123' + example.run() + end + end + + example.run() + + ensure + around_example_repository = RSpec.configuration.hooks.send(:hooks_for, :around, :example) + item_we_added = around_example_repository.items_for(uniquely_identifiable_metadata()).first + around_example_repository.delete(item_we_added, uniquely_identifiable_metadata()) + end + + it 'does not reset ActiveSupport::CurrentAttributes before examples' do + group = + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata()) do + include RSpec::Rails::RailsExampleGroup + + it 'runs normally' do + expect(CurrentAttrsBetweenHooks.request_id).to eq('123') + end + end + + expect( + group.run(failure_reporter) ? true : failure_reporter.exceptions + ).to be true + end + + it 'does not reset ActiveSupport::CurrentAttributes before before-each hooks' do + group = + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata()) do + include RSpec::Rails::RailsExampleGroup + + # Client code will often have test setup blocks within "*_spec.rb" + # files that might set up data or other environmental factors for a + # group of tests in e.g. a "before" hook, but would reasonably expect + # suite-wide 'around' settings to remain intact and not be reset. + # + before :each do | example | + expect(CurrentAttrsBetweenHooks.request_id).to eq('123') + CurrentAttrsBetweenHooks.request_id = '234' + end + + it 'runs normally' do + expect(CurrentAttrsBetweenHooks.request_id).to eq('234') + end + end + + expect( + group.run(failure_reporter) ? true : failure_reporter.exceptions + ).to be true + end + end # "context 'with suite-level around-example hooks configured' ..." end end From f3707d43ba0a7b760ad5ae89f385608a521fcdab Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Thu, 4 Jul 2024 17:58:20 +1200 Subject: [PATCH 02/10] Remove verbose comments in favour of PR reference --- lib/rspec/rails/adapters.rb | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/lib/rspec/rails/adapters.rb b/lib/rspec/rails/adapters.rb index 689f897eb..71d2f42e0 100644 --- a/lib/rspec/rails/adapters.rb +++ b/lib/rspec/rails/adapters.rb @@ -138,30 +138,10 @@ def method_name # @private # - # ActiveSupport::CurrentAttributes::TestHelper uses both before-setup and - # after-teardown hooks to clear attributes. These are run in an awkward - # order relative to RSpec hooks. Client suite-configured "around each" - # hooks run first, the attribute reset hooks next, and contexts or examples - # (along with whatever their defined hooks might be) run last. Consequently - # a suite which sets up around-each-example attributes could fail, because - # the attributes would have been reset by time tests actually run. + # Reset ActiveSupport::CurrentAttributes only *after* tests run, rather + # than before *and* after. # - # Reworking with "before" rather than "around" hooks sidesteps the problem. - # Unfortunately, "executes via a block to clean up after itself" cases such - # as with "ActsAsTenant.without_tenant ..." make such a rework either hard - # or impossible. Besides, even realising that you may need to do this can - # take some significant debugging effort and insight. - # - # The compromise is to use "half" of what ActiveSupport does - just add the - # after-hook. Attributes are now only reset after examples run, but still - # before a suite-wide "around" hook's call to "example.run()" returns. If a - # test suite depended upon current attribute data still being set *after* - # examples within its suite-wide "around" hook, it would fail. This is - # unlikely; it's overwhelmingly common to just *set up* data before a test, - # and usually the only things you're doing afterwards are cleanup. - # - # Include this module to reset under the above compromise, instead of - # including ActiveSupport::CurrentAttributes::TestHelper. + # See https://github.com/rspec/rspec-rails/pull/2774 for more details. # module ActiveSupportCurrentAttributesAdapter extend ActiveSupport::Concern From 7b364d2a1cde86f5ac8e9de352c460a7b1856863 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Thu, 4 Jul 2024 18:00:55 +1200 Subject: [PATCH 03/10] Probably shouldn't leave that debug 'puts' in there! --- lib/rspec/rails/adapters.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/rspec/rails/adapters.rb b/lib/rspec/rails/adapters.rb index 71d2f42e0..413e8b18d 100644 --- a/lib/rspec/rails/adapters.rb +++ b/lib/rspec/rails/adapters.rb @@ -148,7 +148,6 @@ module ActiveSupportCurrentAttributesAdapter included do def after_teardown - puts "AFTER TEARDOWN" super ActiveSupport::CurrentAttributes.reset_all end From beda80743f89ef4922f865ffd02e6cd7642319e0 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Thu, 4 Jul 2024 18:24:10 +1200 Subject: [PATCH 04/10] Address RuboCop warnings (it made some good calls, tho I think parens on 'let' method calls are vital for clarity, personally...) --- .../rails/example/rails_example_group_spec.rb | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 2dc701d8c..12abfd340 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -62,9 +62,11 @@ class CurrentSample < ActiveSupport::CurrentAttributes { configured_around_example_hook: true } end + # rubocop:disable Lint/ConstantDefinitionInBlock class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes attribute :request_id end + # rubocop:enable Lint/ConstantDefinitionInBlock # We have to modify the suite's around-each in RSpec.config, but don't # want to pollute other tests with this (whether or not it is harmless @@ -72,7 +74,7 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # it's necessary use some private APIs to be able to delete the added # hook via 'ensure'. # - around :each do | example | + around :each do | outer_example | # Client code might legitimately want to wrap examples to ensure # all-conditions tidy-up, e.g. "ActsAsTenant.without_tenant do...", @@ -82,23 +84,23 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # time their actual tests, or their test hooks ran. # RSpec.configure do | config | - config.around(:each, uniquely_identifiable_metadata()) do | example | + config.around(:each, uniquely_identifiable_metadata) do | inner_example | CurrentAttrsBetweenHooks.request_id = '123' - example.run() + inner_example.run end end - example.run() + outer_example.run ensure around_example_repository = RSpec.configuration.hooks.send(:hooks_for, :around, :example) - item_we_added = around_example_repository.items_for(uniquely_identifiable_metadata()).first - around_example_repository.delete(item_we_added, uniquely_identifiable_metadata()) + item_we_added = around_example_repository.items_for(uniquely_identifiable_metadata).first + around_example_repository.delete(item_we_added, uniquely_identifiable_metadata) end it 'does not reset ActiveSupport::CurrentAttributes before examples' do group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata()) do + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do include RSpec::Rails::RailsExampleGroup it 'runs normally' do @@ -113,7 +115,7 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes it 'does not reset ActiveSupport::CurrentAttributes before before-each hooks' do group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata()) do + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do include RSpec::Rails::RailsExampleGroup # Client code will often have test setup blocks within "*_spec.rb" @@ -121,7 +123,7 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # group of tests in e.g. a "before" hook, but would reasonably expect # suite-wide 'around' settings to remain intact and not be reset. # - before :each do | example | + before :each do expect(CurrentAttrsBetweenHooks.request_id).to eq('123') CurrentAttrsBetweenHooks.request_id = '234' end @@ -135,6 +137,6 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes group.run(failure_reporter) ? true : failure_reporter.exceptions ).to be true end - end # "context 'with suite-level around-example hooks configured' ..." + end end end From c35bb77744a65a2991996137c9a722b8b6751df1 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Thu, 4 Jul 2024 18:31:43 +1200 Subject: [PATCH 05/10] Use 'in_sub_process' to properly manage global state mutation --- .../rails/example/rails_example_group_spec.rb | 86 +++++++++---------- 1 file changed, 41 insertions(+), 45 deletions(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 12abfd340..80c8a008f 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -1,3 +1,5 @@ +require 'rspec/support/spec/in_sub_process' + module RSpec::Rails RSpec.describe RailsExampleGroup do it 'supports tagged_logger', if: ::Rails::VERSION::MAJOR >= 7 do @@ -68,13 +70,10 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes end # rubocop:enable Lint/ConstantDefinitionInBlock - # We have to modify the suite's around-each in RSpec.config, but don't - # want to pollute other tests with this (whether or not it is harmless - # to do so). There being no public API to read or remove hooks, instead - # it's necessary use some private APIs to be able to delete the added - # hook via 'ensure'. + # This dirties global state, so tests *MUST* remember to use + # "in_sub_process". # - around :each do | outer_example | + before :each do # Client code might legitimately want to wrap examples to ensure # all-conditions tidy-up, e.g. "ActsAsTenant.without_tenant do...", @@ -84,58 +83,55 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # time their actual tests, or their test hooks ran. # RSpec.configure do | config | - config.around(:each, uniquely_identifiable_metadata) do | inner_example | + config.around(:each, uniquely_identifiable_metadata) do | example | CurrentAttrsBetweenHooks.request_id = '123' - inner_example.run + example.run end end - - outer_example.run - - ensure - around_example_repository = RSpec.configuration.hooks.send(:hooks_for, :around, :example) - item_we_added = around_example_repository.items_for(uniquely_identifiable_metadata).first - around_example_repository.delete(item_we_added, uniquely_identifiable_metadata) end it 'does not reset ActiveSupport::CurrentAttributes before examples' do - group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do - include RSpec::Rails::RailsExampleGroup - - it 'runs normally' do - expect(CurrentAttrsBetweenHooks.request_id).to eq('123') + in_sub_process do + group = + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do + include RSpec::Rails::RailsExampleGroup + + it 'runs normally' do + expect(CurrentAttrsBetweenHooks.request_id).to eq('123') + end end - end - expect( - group.run(failure_reporter) ? true : failure_reporter.exceptions - ).to be true + expect( + group.run(failure_reporter) ? true : failure_reporter.exceptions + ).to be true + end end it 'does not reset ActiveSupport::CurrentAttributes before before-each hooks' do - group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do - include RSpec::Rails::RailsExampleGroup - - # Client code will often have test setup blocks within "*_spec.rb" - # files that might set up data or other environmental factors for a - # group of tests in e.g. a "before" hook, but would reasonably expect - # suite-wide 'around' settings to remain intact and not be reset. - # - before :each do - expect(CurrentAttrsBetweenHooks.request_id).to eq('123') - CurrentAttrsBetweenHooks.request_id = '234' + in_sub_process do + group = + RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do + include RSpec::Rails::RailsExampleGroup + + # Client code will often have test setup blocks within "*_spec.rb" + # files that might set up data or other environmental factors for a + # group of tests in e.g. a "before" hook, but would reasonably expect + # suite-wide 'around' settings to remain intact and not be reset. + # + before :each do + expect(CurrentAttrsBetweenHooks.request_id).to eq('123') + CurrentAttrsBetweenHooks.request_id = '234' + end + + it 'runs normally' do + expect(CurrentAttrsBetweenHooks.request_id).to eq('234') + end end - it 'runs normally' do - expect(CurrentAttrsBetweenHooks.request_id).to eq('234') - end - end - - expect( - group.run(failure_reporter) ? true : failure_reporter.exceptions - ).to be true + expect( + group.run(failure_reporter) ? true : failure_reporter.exceptions + ).to be true + end end end end From 8d32e03b7c672ed23b716d1bc44f101f415c0648 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Mon, 8 Jul 2024 10:07:03 +1200 Subject: [PATCH 06/10] Update spec/rspec/rails/example/rails_example_group_spec.rb Co-authored-by: Phil Pirozhkov --- spec/rspec/rails/example/rails_example_group_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 80c8a008f..02af8f592 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -73,7 +73,7 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # This dirties global state, so tests *MUST* remember to use # "in_sub_process". # - before :each do + def configure_rspec_to_set_current_attrs_before_around_example # Client code might legitimately want to wrap examples to ensure # all-conditions tidy-up, e.g. "ActsAsTenant.without_tenant do...", From 5be22278c4d87d07673c0acac1bf48fac31738b8 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Mon, 8 Jul 2024 10:07:14 +1200 Subject: [PATCH 07/10] Update spec/rspec/rails/example/rails_example_group_spec.rb Co-authored-by: Phil Pirozhkov --- spec/rspec/rails/example/rails_example_group_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 02af8f592..082d404fa 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -82,8 +82,8 @@ def configure_rspec_to_set_current_attrs_before_around_example # anything set in CurrentAttributes here to suddenly be reset by the # time their actual tests, or their test hooks ran. # - RSpec.configure do | config | - config.around(:each, uniquely_identifiable_metadata) do | example | + RSpec.configure do |config| + config.around(:each) do |example| CurrentAttrsBetweenHooks.request_id = '123' example.run end From f8e09f502904537cf86904e13113d6f33f436883 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Mon, 8 Jul 2024 10:07:24 +1200 Subject: [PATCH 08/10] Update spec/rspec/rails/example/rails_example_group_spec.rb Co-authored-by: Phil Pirozhkov --- spec/rspec/rails/example/rails_example_group_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 082d404fa..e8639fc3b 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -91,7 +91,6 @@ def configure_rspec_to_set_current_attrs_before_around_example end it 'does not reset ActiveSupport::CurrentAttributes before examples' do - in_sub_process do group = RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do include RSpec::Rails::RailsExampleGroup From cc2a7f3fd108d961179ec3361eedf4fcdf6293da Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Mon, 8 Jul 2024 10:07:31 +1200 Subject: [PATCH 09/10] Update spec/rspec/rails/example/rails_example_group_spec.rb Co-authored-by: Phil Pirozhkov --- spec/rspec/rails/example/rails_example_group_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index e8639fc3b..3fd474e1d 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -91,6 +91,7 @@ def configure_rspec_to_set_current_attrs_before_around_example end it 'does not reset ActiveSupport::CurrentAttributes before examples' do + configure_rspec_to_set_current_attrs_before_around_example group = RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do include RSpec::Rails::RailsExampleGroup From 388c0a9f0de3e4419460f3f431c09a1efc6e5251 Mon Sep 17 00:00:00 2001 From: Andrew Hodgkinson Date: Mon, 8 Jul 2024 10:27:09 +1200 Subject: [PATCH 10/10] Figured out test issues & fixed --- .../rails/example/rails_example_group_spec.rb | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/rspec/rails/example/rails_example_group_spec.rb b/spec/rspec/rails/example/rails_example_group_spec.rb index 3fd474e1d..1a55c4c94 100644 --- a/spec/rspec/rails/example/rails_example_group_spec.rb +++ b/spec/rspec/rails/example/rails_example_group_spec.rb @@ -60,9 +60,6 @@ class CurrentSample < ActiveSupport::CurrentAttributes end context 'with suite-level around-example hooks configured', if: ::Rails::VERSION::MAJOR >= 7 do - let(:uniquely_identifiable_metadata) do - { configured_around_example_hook: true } - end # rubocop:disable Lint/ConstantDefinitionInBlock class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes @@ -74,7 +71,7 @@ class CurrentAttrsBetweenHooks < ActiveSupport::CurrentAttributes # "in_sub_process". # def configure_rspec_to_set_current_attrs_before_around_example - + # # Client code might legitimately want to wrap examples to ensure # all-conditions tidy-up, e.g. "ActsAsTenant.without_tenant do...", # wherein an "around" hook is the only available solution, often used @@ -84,6 +81,7 @@ def configure_rspec_to_set_current_attrs_before_around_example # RSpec.configure do |config| config.around(:each) do |example| + expect(CurrentAttrsBetweenHooks.request_id).to be_nil CurrentAttrsBetweenHooks.request_id = '123' example.run end @@ -91,9 +89,11 @@ def configure_rspec_to_set_current_attrs_before_around_example end it 'does not reset ActiveSupport::CurrentAttributes before examples' do - configure_rspec_to_set_current_attrs_before_around_example + in_sub_process do + configure_rspec_to_set_current_attrs_before_around_example + group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do + RSpec::Core::ExampleGroup.describe('A group') do include RSpec::Rails::RailsExampleGroup it 'runs normally' do @@ -109,8 +109,10 @@ def configure_rspec_to_set_current_attrs_before_around_example it 'does not reset ActiveSupport::CurrentAttributes before before-each hooks' do in_sub_process do + configure_rspec_to_set_current_attrs_before_around_example + group = - RSpec::Core::ExampleGroup.describe('A group', uniquely_identifiable_metadata) do + RSpec::Core::ExampleGroup.describe('A group') do include RSpec::Rails::RailsExampleGroup # Client code will often have test setup blocks within "*_spec.rb"