views:

745

answers:

10

I'm having a test hang in our rails app can't figure out which one (since it hangs and doesn't get to the failure report). I found this blog post http://bmorearty.wordpress.com/2008/06/18/find-tests-more-easily-in-your-testlog/ which adds a setup hook to print the test name but when I try to do the same thing it gives me an error saying wrong number of arguments for setup (1 for 0). Any help at all would be appreciated.

A: 

can you just hit ctrl+c to halt the execution and it will display the stack trace of where you halted the execution?

TonyLa
It will probably be difficult to do this at exactly the right time.
nertzy
A: 

The stack trace is only about 15 lines, all of which are deep in some gem so I can't see what test is actually causing the problem.

John Duff
A: 
mwilliams
The test is hanging, not failing, so this answer is not relevant.
James Baker
A: 

Okay, that's grand, if we didn't already have 500 tests written with Test/Unit we might consider it. Test/Unit also displays a report at the end which shows what tests failed and on which lines, the problem is the test is HANGING so it doesn't get to the reporting stage. RSpec would have the same problem if the test hung.

John Duff
A: 

The definition in the blog post is shoulda specific (the setup(&block) method is defined in the module Thoughtbot::Shoulda in context.rb. shoulda.rb then has TestCase extend that module).

The definition for pure test::unit is

# File test/unit/testcase.rb, line 100
      def setup
      end

what you could do is

def setup
  log_test
end  

private   

def log_test   
  if Rails::logger  
    # When I run tests in rake or autotest I see the same log message multiple times per test for some reason.   
    # This guard prevents that.   
  unless @already_logged_this_test  
    Rails::logger.info "\n\nStarting #{@method_name}\n#{'-' * (9 + @method_name.length)}\n"  
  end  
  @already_logged_this_test = true  
end


edit

if you really don't want to edit your files you can risk reopenning test case and extend run instead :

class Test::Unit::TestCase   
  alias :old_run :run
  def run 
    log_test
    old_run
  end
end

this should work (I don't have ruby around to test though)


I give up ! (in frustration)

I checked the code and rails actually does magic behind the scene which is probably why redefining run doesn't work.

The thing is : part of the magic is including ActiveSupport::CallBack and creating callbacks for setup and teardown.

which means

class Test::Unit::TestCase
  setup :log_test  

  private   

  def log_test   
    if Rails::logger  
      # When I run tests in rake or autotest I see the same log message multiple times per test for some reason.   
      # This guard prevents that.   
      unless @already_logged_this_test  
        Rails::logger.info "\n\nStarting #{@method_name}\n#{'-' * (9 + @method_name.length)}\n"  
      end  
      @already_logged_this_test = true  
    end  
  end  
end

should definitely work

and actually running tests with it does work. where I am confused is that this is the first thing I tried and it failed with the same error you got

Jean
A: 

@Jean - if I just define setup in testcase.rb it will get blown away when we define setup in the actual test (or will override the setup in the individual tests). I could go through each of our test files and add log_test to each setup method, that's pretty annoying though, figured there would be an easier way to hook into that with ruby.

edit

@Jean - We went through the same thought process :). Trying that worked when running an individual test class, but when running the whole suite i got a stack error, it seemed to be caught in a loop on the run call (it output the first tests name 30 times before crashing).

John Duff
+5  A: 

The printing of the test name is the responsibility of the TestRunner. If you are running your tests from the command line you can specify the -v option, to print out the test case names.

example:

ruby test_Foo.rb -v
Loaded suite test_Foo
Started
test_blah(TestFoo): .
test_blee(TestFoo): .

Finished in 0.007 seconds.

2 tests, 15 assertions, 0 failures, 0 errors
Aaron Hinni
Is there an equivalent way to do this from the Rails `rake tests` task?
nertzy
rake test:units TESTOPTS="-v"
allenwei
+3  A: 

This is what I use, in test_helper.rb

class Test::Unit::TestCase
  # ...

  def setup_with_naming 
    unless @@named[self.class.name]
      puts "\n#{self.class.name} "
      @@named[self.class.name] = true
    end
    setup_without_naming
  end
  alias_method_chain :setup, :naming unless defined? @@aliased
  @@aliased = true  
end

The @@aliased variable keeps it from being re-aliased when you run it on multiple files at once; @@named keeps the name from being displayed before every test (just before the first to run).

Ben Scofield
A: 

Thanks everyone for the help, I ended up going through the tests and adding a call to log_name in each of the setup methods for each test file before these last couple answers came up. Thanks again.

John Duff
+1  A: 

If you run test using rake it will work:

rake test:units TESTOPTS="-v" 
allenwei