Cucumber vs Rails Fixtures


#1

Cucumberists:

Apologies for not jumping into some wild alternate fixture (or mock!)
system,
but the unit tests at my new day gig are >cough< hanging by a thread as
it is.

I need to show off some cute Cuke, without rocking the boat!

How do I actually use real, pre-existing Rails fixtures, the same as the
unit
tests use? For familiarity?

Putting this at the top of the step.rb seems just a leeettle bit
tacky…

$fixtures_installed ||= (
ENV[‘RAILS_ENV’] = ‘test’
RAILS_ENV.replace(‘test’)
system(‘rake db:fixtures:load’) )

I have attempted to load Rails Fixtures on demand before, and I’m the
first to
admit their architecture sucks - loading them on demand ain’t pretty!

And exactly why was ‘rake features’ running in RAILS_ENV=development
mode? Do
developers like having their scratch database screwed up each time
they run
fixtures? Enquiring minds want to know!


Phlip


#2

Ben M. wrote:

http://wiki.github.com/aslakhellesoy/cucumber/fixtures

Ding! That would have been my next click in my Googling. Let’s hope this
thread
pushes that up.

http://groups.google.com/group/cukes

What, no gmane yet?? (-:


Phlip


#3

Phlip wrote:

Cucumberists:

FYI, Cucumber now has it’s own mailing list:
http://groups.google.com/group/cukes

Apologies for not jumping into some wild alternate fixture (or mock!)
system, but the unit tests at my new day gig are >cough< hanging by a
thread as it is.

I need to show off some cute Cuke, without rocking the boat!

How do I actually use real, pre-existing Rails fixtures, the same as
the unit tests use? For familiarity?

http://wiki.github.com/aslakhellesoy/cucumber/fixtures

-Ben


#4

I would have preferred: “I have set up GMane”

Thanks Philip :wink:


#5

What, no gmane yet?? (-:

I would have preferred: “I have set up GMane”

Thanks Philip :wink:

Sorry about the spelling Phlip

Aklas


#6

aslak hellesoy wrote:

http://groups.google.com/group/cukes

What, no gmane yet?? (-:

I would have preferred: “I have set up GMane”

Netiquette: I would not set someone else’s group up on GMane - even if
it were
just a Google Group…


Phlip
http://flea.sourceforge.net/resume.html


#7

How do I actually use real, pre-existing Rails fixtures, the same as
the unit tests use? For familiarity?

What I was missing is the regular use of fixtures as in rspec or test
unit, like so:

u = users(:bob)
u.email = “aaa”
u.should_not be_valid

This link

http://wiki.github.com/aslakhellesoy/cucumber/fixtures

described how to get fixtures loaded for the entire suite, so that you
can say:

u = User.find(1)

or

u = User.find_by_name(“Bob”)

this is kind of a drag, if you have a well formed fixture file with
symbolic names, etc.

So I came up with this (which was developed and tested in Cucumber gem
version 0.2.3, and I haven’t tried it yet with the latest 0.3.9):

Add this to your env file:

Fixtures.reset_cache
fixtures_folder = File.join(RAILS_ROOT, ‘test’, ‘fixtures’)
fixtures = Dir[File.join(fixtures_folder, ‘.yml’)].map {|f|
File.basename(f, ‘.yml’) }
fixtures << Dir[File.join(fixtures_folder, '
.csv’)].map {|f|
File.basename(f, ‘.csv’) }

If your fixture files are named differently from the classes they

refer to,

you also need to do this:

class_table_mappings = {:table_name_in_db => class_name}

Fixtures.create_fixtures(fixtures_folder, fixtures,

class_table_mappings)

otherwise:

This will populate the test database tables

Fixtures.create_fixtures(fixtures_folder, fixtures)

The following will define methods that can access symbolic fixture

names,

as in users(:bob)

World do |world|

(class << world; self; end).class_eval do
@@fixture_cache = {}
fixtures.each do |table_name|
table_name = table_name.to_s.tr(’.’, ‘_’)
define_method(table_name) do |*fixture_symbols|
@@fixture_cache[table_name] ||= {}

    instances = fixture_symbols.map do |fixture_symbol|
      if fix = 

Fixtures.cached_fixtures(ActiveRecord::Base.connection,
table_name)[fixture_symbol.to_s]
@@fixture_cache[table_name][fixture_symbol] ||= fix.find #
find model.find’s the instance
else
raise StandardError, “No fixture with name
‘#{fixture_symbol}’ found for table ‘#{table_name}’”
end
end
instances.size == 1 ? instances.first : instances
end
end
end
world
end


#8

I’ve updated http://wiki.github.com/aslakhellesoy/cucumber/fixtures
accordingly.


#9

This still wasn’t fully working; I posted too soon. See here for the
final and working version:
http://wiki.github.com/aslakhellesoy/cucumber/fixtures


#10

I do this:

Fixtures.reset_cache
fixtures_folder = File.join(RAILS_ROOT, ‘test’, ‘fixtures’)
fixtures = Dir[File.join(fixtures_folder, ‘*.yml’)].map {|f|
File.basename(f, ‘.yml’) }
fixture_class_names = {} # or whatever needed
Fixtures.create_fixtures(fixtures_folder, fixtures, fixture_class_names)


#11

The method I posted last week only works for Cucumber prior to 0.2.3.2.

For 0.2.3.2 and later, you cannot pass a block to the World more than
once, and thus the new way would be (in env.rb):

module FixtureAccess

def self.included(base)
(class << base; self; end).class_eval do
@@fixture_cache = {}
fixtures.each do |table_name|
table_name = table_name.to_s.tr(’.’, ‘_’)
define_method(table_name) do |*fixture_symbols|
@@fixture_cache[table_name] ||= {}

      instances = fixture_symbols.map do |fixture_symbol|
        if fix = 

Fixtures.cached_fixtures(ActiveRecord::Base.connection,
table_name)[fixture_symbol.to_s]
@@fixture_cache[table_name][fixture_symbol] ||= fix.find

find model.find’s the instance

        else
          raise StandardError, "No fixture with name 

‘#{fixture_symbol}’ found for table ‘#{table_name}’"
end
end
instances.size == 1 ? instances.first : instances
end
end
end
end

end

… then …

World(FixtureAccess)


#12

Yi Wen wrote:

I do this:

Fixtures.reset_cache
fixtures_folder = File.join(RAILS_ROOT, ‘test’, ‘fixtures’)
fixtures = Dir[File.join(fixtures_folder, ‘*.yml’)].map {|f|
File.basename(f, ‘.yml’) }
fixture_class_names = {} # or whatever needed
Fixtures.create_fixtures(fixtures_folder, fixtures, fixture_class_names)

Sure, that’ll load fixtures and let you access them, e.g. with:

User.find(1)

What I wanted is to be able to access fixtures with:

users(:john)

Hence all the heavy lifting. It works now as described on the github
wiki page.