Permalink
Browse files

scrub instance variables from test cases on teardown

this prevents test state from accumulating, resulting in leaked
objects and slow tests due to overactive GC.
  • Loading branch information...
1 parent 8378a44 commit b5cf2b4b82de877c07bb2cca02085d2b3ec195e0 @jamis jamis committed Jan 19, 2011
@@ -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"
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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

0 comments on commit b5cf2b4

Please sign in to comment.