Como preparar fixtures de forma rápida y sencilla

Vamos con un post rapidito. Llevo unos dias haciendo functional tests, y el tema de los fixtures, como mucha gente ya ha dicho, es un asco.

Para ello me he creado una tarea Rake sencilla que puede ayudaros:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  desc "Prepare fixtures"
  task :prepare_fixtures => :environment do
 
    class FixturePreparer
      class << self
        def generate(name, collection)
          f = File.open("test/fixtures/#{name}.yml",'w+')
          collection_data = collection.map {|x| { (block_given? ? (yield x) : (x.respond_to?(:slug) ? x.slug : x.id)) => x.attributes }.to_yaml }
          collection_data.each {|item| f.puts item.sub(/.*\n/,'') }
          f.close
        end
      end
    end
 
    puts "Preparing Users"
    FixturePreparer.generate('users', User.find([1,2,3]))
 
    puts "Preparing Groups"
    FixturePreparer.generate('groups', Group.find([1,2,3,4]))
    FixturePreparer.generate('groups_users', GroupsUser.find(:all, :conditions => { :group_id => [1,2,3,4] }))
 
    puts "Preparing Discussions"
    discussions = Discussion.find(:all, :conditions => { :discutable_type => 'Group', :discutable_id => [1,2,3,4] })
    FixturePreparer.generate('discussions', discussions)
    FixturePreparer.generate('discussions_users', DiscussionsUser.all(:conditions => { :discussion_id => discussions.map(&:id) }) ) {|item| "#{item.user_id}-#{item.discussion_id}" }
    FixturePreparer.generate('discussion_categories', DiscussionCategory.all(:conditions => { :discussion_id => discussions.map(&:id) }) ) {|item| "#{item.discussion_id}-#{item.slug}" }
    FixturePreparer.generate('discussion_topics', DiscussionTopic.all(:conditions => { :discussion_id => discussions.map(&:id) }) )
    FixturePreparer.generate('discussion_posts', DiscussionPost.all(:conditions => { :discussion_id => discussions.map(&:id) }) )
 
    puts "Preparing Countries"
    FixturePreparer.generate('countries', Country.all)
 
  end

Creo que el código es auto-explicativo, pero hagamos un repaso rápido:
El tema importante es la classe FixturePreparer, al cual se le pasa un nombre y un array de ActiveRecords, opcionalmente se le puede pasar un bloque.

El nombre será el nombre del fichero a guardar, el array de ActiveRecords es la colección de registros que se quieren poner en el fixture, y por último, el bloque. El bloque es opcional y sirve para poner un identificador único a cada registro dentro del fixture, si no le pasamos ningún bloque, el identificador será el slug, y si no tiene slug, pues el id. En caso que le pasemos un bloque, evaluará el bloque para cada registro. Hay que tener en cuenta que el identificador de registro DEBE SER UNICO en cada yml.

De esta forma, puedes generarte un pequeño set de datos minimos a partir de tu db de desarrollo e ir actualizando los fixtures conforme actualizas tu base de datos.

El código es tan pequeño que no he creido necesario crear un repositorio en github para permitir forks, etc… pero si alguien esta interesado, lo creo!

Suerte con los tests. ;)

Editado: Xavier Noria, siempre en su linea de expresiones regulares varias, nos proporciona un parche para hacer mejor la clase FixturePreparer, gracias!

1 Response to “Como preparar fixtures de forma rápida y sencilla”


  1. 1

Leave a Reply