This project is archived and is in readonly mode.

#261 ✓wontfix
Menno

Fixtures names can't start with 'test'

Reported by Menno | May 27th, 2008 @ 03:15 PM

After moving from Rails 1.2 to 2.0.2 using fixtures whose name starts with 'test' fails. Running 'rake' when having fixture test_whatevers.yml results in an

1) Error:

test_whatevers(ActionController::TestCase):

ArgumentError: wrong number of arguments (0 for 1)

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `initialize'

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `new'

/var/lib/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/test_case.rb:48:in `setup_without_fixtures'

/var/lib/gems/1.8/gems/activerecord-2.0.2/lib/active_record/fixtures.rb:979:in `full_setup'

/var/lib/gems/1.8/gems/activesupport-2.0.2/lib/active_support/testing/default.rb:7:in `run'

To reproduce

  • Create new project: 'rails foo'
  • In foo, create a model TestWhatever: 'script/generate model TestWhatever'
  • Migrate: 'rake db:migrate'
  • Run tests: 'rake'
  • See expection above.

All is fine when the model is named 'TesxWhatever' or 'WhateverTest'.

Comments and changes to this ticket

  • Menno

    Menno May 27th, 2008 @ 03:18 PM

    • Title changed from “ArgumentError using fixtures named test...” to “ArgumentError using fixtures named test*”
  • Menno

    Menno May 30th, 2008 @ 04:12 PM

    It turns out things are messed up by line 54 of Ruby 1.8.6's test/unit/testcase.rb:

    tests = method_names.delete_if {|method_name| method_name !~ /^test./}
    

    This is in the self.suite method which "Rolls up all of the test* methods in the fixture into one suite, creating a new instance of the fixture for each method."

    When you remove your fixture names from method_names, i.e. add a line tests.delete("test_whatevers") after line 54, all is fine again. But obviously this is no solution.

  • Menno

    Menno May 30th, 2008 @ 05:54 PM

    • Title changed from “ArgumentError using fixtures named test*” to “Fixtures names can't start with 'test'”
  • oddlyzen

    oddlyzen May 30th, 2008 @ 06:43 PM

    wouldn't it be better (instead of checking the method_name string) to check the module/class hierarchy for the testing module..? checking the string/name assumes that everyone is going to follow the conventions. we know that's not true, likely, or maybe even possible.

  • josh

    josh July 17th, 2008 @ 02:08 AM

    • State changed from “new” to “wontfix”
    • Tag set to 2.0-stable, actionpack, activerecord, bug
  • Menno

    Menno July 17th, 2008 @ 09:36 AM

    Thanks for the update. Should I interpret the tags as "fixed in 2.1"?

  • Menno

    Menno September 18th, 2008 @ 10:45 AM

    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, bug

    Issue still present in Rails 2.1.1

  • Rob Lucas

    Rob Lucas October 2nd, 2008 @ 12:00 PM

    I'm getting this bug as a result of having a model called "Testimonial". It seems that I can't have fixtures at all for this model because of this bug. Surely we can handle these things more intelligently than this!

  • Rob Lucas

    Rob Lucas October 2nd, 2008 @ 05:07 PM

    Rails apparently regards "Test" as a reserved name for controllers, probably for this kind of reason. When trying to generate a controller just called "Test", I get the following response in Rails 2.1.1:


    The name 'Test' is either already used in your application or reserved by Ruby on Rails.

    Please choose an alternative and run this generator again.

    Suggestions:

    trial trial run tryout mental test mental testing psychometric test examination exam run prove try try out examine essay screen

    quiz

    But models with names such as "testimonial", "testament" etc should certainly still be possible, and I can't really see why something like "test_driver" shouldn't work either. I've managed to get around this problem by hacking the line of test/unit/testcase.rb that is mentioned by Menno above. Rather than going in and hacking the actual original file, I'm overriding it by requiring a file in my troubled unit tests like:

    
    module Test
      module Unit
        class TestCase
            # Require this file in any unit tests for models starting with the letters "test".
            # Overrides the suite method in Ruby's test/unit/testcase.rb so that we don't end
            # up trying to run a spurious unit test method of the same name as our model
            def self.suite
              method_names = public_instance_methods(true)
              tests = method_names.delete_if {|method_name| method_name !~ /^test./ || method_name == "test_whatevers"}
              suite = TestSuite.new(name)
              tests.sort.each do
                |test|
                catch(:invalid_test) do
                  suite << new(test)
                end
              end
              if (suite.empty?)
                catch(:invalid_test) do
                  suite << new("default_test")
                end
              end
              return suite
            end
        end
      end
    end
    
  • Rob Lucas

    Rob Lucas October 2nd, 2008 @ 05:08 PM

    Rails apparently regards "Test" as a reserved name for controllers, probably for this kind of reason. When trying to generate a controller just called "Test", I get the following response in Rails 2.1.1:


    The name 'Test' is either already used in your application or reserved by Ruby on Rails.

    Please choose an alternative and run this generator again.

    Suggestions:

    trial trial run tryout mental test mental testing psychometric test examination exam run prove try try out examine essay screen quiz


    But models with names such as "testimonial", "testament" etc should certainly still be possible, and I can't really see why something like "test_driver" shouldn't work either. I've managed to get around this problem by hacking the line of test/unit/testcase.rb that is mentioned by Menno above. Rather than going in and hacking the actual original file, I'm overriding it by requiring a file in my troubled unit tests like:

    
    module Test
      module Unit
        class TestCase
            # Require this file in any unit tests for models starting with the letters "test".
            # Overrides the suite method in Ruby's test/unit/testcase.rb so that we don't end
            # up trying to run a spurious unit test method of the same name as our model
            def self.suite
              method_names = public_instance_methods(true)
              tests = method_names.delete_if {|method_name| method_name !~ /^test./ || method_name == "test_whatevers"}
              suite = TestSuite.new(name)
              tests.sort.each do
                |test|
                catch(:invalid_test) do
                  suite << new(test)
                end
              end
              if (suite.empty?)
                catch(:invalid_test) do
                  suite << new("default_test")
                end
              end
              return suite
            end
        end
      end
    end
    
  • Mike Boone

    Mike Boone January 31st, 2010 @ 03:30 PM

    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, bug

    There is still a problem in Rails 2.3.5 with creating a model beginning with 'Test'.

    rails myapp
    cd myapp
    script/generate model testimonial name:string comment:text
    rake db:migrate
    rake test:units

    1) Error: testimonials(ActionView::TestCase):
    TypeError: wrong argument type Class (expected Module)

    8 tests, 1 assertions, 0 failures, 1 errors
    rake aborted!

  • Hery

    Hery March 23rd, 2010 @ 10:02 AM

    • Tag changed from 2.0-stable, actionpack, activerecord, bug to 2.0-stable, actionpack, activerecord, activesupport, bug, testcase

    Hi, I found the fix for rails 3 and test-unit using minitest. It is minitest bug :

    In minitest/unit.rb

      def self.test_methods
        methods = public_instance_methods(true).grep(/^test/).map { |m|
          m.to_s
        }.sort
    
        if self.test_order == :random then
          max = methods.size
          methods = methods.sort_by { rand(max) }
        end
    
        methods
      end
    

    You just have to patch your test/test_helper.rb

    class ActiveSupport::TestCase
      # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order.
      #
      # Note: You'll currently still have to declare fixtures explicitly in integration tests
      # -- they do not yet inherit this setting
      fixtures :all
    
      # Fix minitest bug : all public methods beginning with 'test' are considered as test_methods ... that is not true if we have a resource called testimony
      # testimony_path will not be found and tests will fail!
      def self.test_methods
        methods = public_instance_methods(true).grep(/^test$|^test_/).map { |m|
          m.to_s
        }.sort
    
        if self.test_order == :random then
          max = methods.size
          methods = methods.sort_by { rand(max) }
        end
    
        methods
      end
    
      # Add more helper methods to be used by all tests here...
    
    end
    

    Should it be included in ActiveSupport::TestCase ?

  • chris finne

    chris finne August 16th, 2010 @ 10:55 AM

    Workaround is pretty easy. Just rename your fixtures file, then associate that odd name with the proper class.

    testimonials.yml => atestimonials.yml

    and in test/test_helper.rb

    class ActiveSupport::TestCase
      ...
      set_fixture_class :atestimonials => Testimonial
      ...
    end
    
  • Mike Boone

    Mike Boone August 28th, 2010 @ 03:36 PM

    @Chris, thanks for the workaround. I tried it and it works.

    I still don't understand why this is a "wontfix". Seems a legitimate bug. Unless there is documentation that states "don't name models with any word that begins with 'Test'"?

  • Ryan Bigg

    Ryan Bigg October 9th, 2010 @ 09:44 PM

    • Tag cleared.
    • Importance changed from “” to “Low”

    Automatic cleanup of spam.

  • Jeff Kreeftmeijer
  • bingbing

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

Pages