Skip to content

Commit

Permalink
scrub instance variables from test cases on teardown
Browse files Browse the repository at this point in the history
this prevents test state from accumulating, resulting in leaked
objects and slow tests due to overactive GC.
  • Loading branch information
jamis committed Jan 19, 2011
1 parent 8378a44 commit b5cf2b4
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
2 changes: 2 additions & 0 deletions activesupport/lib/active_support/test_case.rb
Expand Up @@ -3,6 +3,7 @@
require 'active_support/testing/assertions'
require 'active_support/testing/deprecation'
require 'active_support/testing/declarative'
require 'active_support/testing/garbage_collection'

begin
gem 'mocha', ">= 0.9.7"
Expand Down Expand Up @@ -36,5 +37,6 @@ class TestCase < ::Test::Unit::TestCase
include ActiveSupport::Testing::Assertions
include ActiveSupport::Testing::Deprecation
extend ActiveSupport::Testing::Declarative
include ActiveSupport::Testing::GarbageCollection
end
end
19 changes: 19 additions & 0 deletions activesupport/lib/active_support/testing/garbage_collection.rb
@@ -0,0 +1,19 @@
module ActiveSupport
module Testing
module GarbageCollection
def self.included(base)
base.teardown :scrub_leftover_instance_variables
end

private

RESERVED_INSTANCE_VARIABLES = %w(@test_passed @passed @method_name @__name__ @_result).map(&:to_sym)

def scrub_leftover_instance_variables
(instance_variables.map(&:to_sym) - RESERVED_INSTANCE_VARIABLES).each do |var|
remove_instance_variable(var)
end
end
end
end
end
18 changes: 18 additions & 0 deletions activesupport/test/test_case_test.rb
Expand Up @@ -74,5 +74,23 @@ def test_true; assert true end

assert_match %r{oh noes}, exception.message
end

def test_teardown_should_scrub_instance_variables
tc = Class.new(TestCase) do
def test_true; @alpha = "a"; assert_equal "a", @alpha; end
end

test_name = 'test_true'
fr = FakeRunner.new

test = tc.new test_name
test.run(fr) {}

passed_var = IS_MINITEST ? :@passed : :@test_passed
ivars = test.instance_variables.map(&:to_sym)

assert ivars.include?(passed_var), "#{passed_var} should not have been scrubbed"
assert !ivars.include?(:@alpha), "@alpha should have been scrubbed"
end
end
end
4 changes: 2 additions & 2 deletions activesupport/test/test_test.rb
Expand Up @@ -143,7 +143,7 @@ class SetupAndTeardownTest < ActiveSupport::TestCase
def test_inherited_setup_callbacks
assert_equal [:reset_callback_record, :foo], self.class.setup_callback_chain.map(&:method)
assert_equal [:foo], @called_back
assert_equal [:foo, :sentinel, :foo], self.class.teardown_callback_chain.map(&:method)
assert_equal [:scrub_leftover_instance_variables, :foo, :sentinel, :foo], self.class.teardown_callback_chain.map(&:method)
end

def setup
Expand Down Expand Up @@ -174,7 +174,7 @@ class SubclassSetupAndTeardownTest < SetupAndTeardownTest
def test_inherited_setup_callbacks
assert_equal [:reset_callback_record, :foo, :bar], self.class.setup_callback_chain.map(&:method)
assert_equal [:foo, :bar], @called_back
assert_equal [:foo, :sentinel, :foo, :bar], self.class.teardown_callback_chain.map(&:method)
assert_equal [:scrub_leftover_instance_variables, :foo, :sentinel, :foo, :bar], self.class.teardown_callback_chain.map(&:method)
end

protected
Expand Down

0 comments on commit b5cf2b4

Please sign in to comment.