Skip to content

Commit 6ad3d0e

Browse files
committed
Share already loaded fixtures across test classes
`self.class` is a fairly narrow cache key, so it doesn't hit that much, but more importantly, since nothing clears that cache, on large test suites it keeps growing extremely large. Using the list of fixtures as a cache key doesn't strictly solve the growth issue, but most classes actually load all fixtures so this should shrink the cache size considerably.
1 parent c13b82a commit 6ad3d0e

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

activerecord/lib/active_record/test_fixtures.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def fixtures(*fixture_set_names)
7979
fixture_set_names = fixture_set_names.flatten.map(&:to_s)
8080
end
8181

82-
self.fixture_table_names |= fixture_set_names
82+
self.fixture_table_names = (fixture_table_names | fixture_set_names).sort
8383
setup_fixture_accessors(fixture_set_names)
8484
end
8585

@@ -131,17 +131,17 @@ def setup_fixtures(config = ActiveRecord::Base)
131131

132132
@fixture_cache = {}
133133
@fixture_connections = []
134+
@fixture_cache_key = [self.class.fixture_table_names.dup, self.class.fixture_paths.dup, self.class.fixture_class_names.dup]
134135
@@already_loaded_fixtures ||= {}
135136
@connection_subscriber = nil
136137
@saved_pool_configs = Hash.new { |hash, key| hash[key] = {} }
137138

138139
# Load fixtures once and begin transaction.
139140
if run_in_transaction?
140-
if @@already_loaded_fixtures[self.class]
141-
@loaded_fixtures = @@already_loaded_fixtures[self.class]
142-
else
143-
@loaded_fixtures = load_fixtures(config)
144-
@@already_loaded_fixtures[self.class] = @loaded_fixtures
141+
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key]
142+
unless @loaded_fixtures
143+
@@already_loaded_fixtures.clear
144+
@loaded_fixtures = @@already_loaded_fixtures[@fixture_cache_key] = load_fixtures(config)
145145
end
146146

147147
# Begin transactions for connections already established
@@ -179,7 +179,7 @@ def setup_fixtures(config = ActiveRecord::Base)
179179
# Load fixtures for every test.
180180
else
181181
ActiveRecord::FixtureSet.reset_cache
182-
@@already_loaded_fixtures[self.class] = nil
182+
@@already_loaded_fixtures.clear
183183
@loaded_fixtures = load_fixtures(config)
184184
end
185185

activerecord/test/cases/fixtures_test.rb

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,7 @@ class MultipleFixturesTest < ActiveRecord::TestCase
783783
fixtures :developers, :accounts
784784

785785
def test_fixture_table_names
786-
assert_equal %w(topics developers accounts), fixture_table_names
786+
assert_equal %w(accounts developers topics), fixture_table_names
787787
end
788788
end
789789

@@ -815,7 +815,7 @@ class OverlappingFixturesTest < ActiveRecord::TestCase
815815
fixtures :developers, :accounts
816816

817817
def test_fixture_table_names
818-
assert_equal %w(topics developers accounts), fixture_table_names
818+
assert_equal %w(accounts developers topics), fixture_table_names
819819
end
820820
end
821821

@@ -1163,6 +1163,8 @@ def blank_teardown; end
11631163
alias_method :teardown_fixtures, :blank_teardown
11641164
alias_method :teardown, :blank_teardown
11651165

1166+
fixtures rand.to_s # bypass fixtures cache
1167+
11661168
def test_no_rollback_in_teardown_unless_transaction_active
11671169
assert_equal 0, ActiveRecord::Base.connection.open_transactions
11681170
assert_raise(RuntimeError) { ar_setup_fixtures }

activerecord/test/cases/view_test.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ def drop_view(name)
101101

102102
class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
103103
include SchemaDumpingHelper
104+
105+
self.use_transactional_tests = false
104106
fixtures :books
105107

106108
class Paperback < ActiveRecord::Base; end

0 commit comments

Comments
 (0)