He comenzado a implementar los tests en una aplicación de Rails que tengo en funcionamiento y he encontrado unos cuantos problemas con las fixtures, al intentar ejecutar las pruebas desde una base de datos en memoria y con código antiguo, a continuación pongo como los he ido solucionando, para tenerlos anotados en algún lugar, y espero que le sirva a alguien en el futuro.

Nota: antes que nada, ahora mismo estoy usando Rails edge en la revisión revisión 5345, aunque creo que no hay ningún cambio respecto a Rails 1.1.x.

Ejecutando los tests desde una base de datos en memoria

Idea: Ejecutar los tests en tablas cargadas en memoria para que éstos se ejecuten mucho más rápido. Uso sqlite3 por lo que la configuración del apartado test de database.yml es la siguiente:


test:   adapter: sqlite3
database: ”:memory:”

Con esta aproximación la base de datos se debe crear en memoria al principio de la ejecución de los tests y al finalizar se libera esta memoria. Para los tests creen la base de datos al comenzar a ejecutarse disponemos del plugin memory_test_fix, que se puede instalar así:


script/plugin install http://topfunky.net/svn/plugins/memory_test_fix

Configuración de las fixtures

Por defecto en las nuevas versiones de Rails (1.0+) las fixtures vienen configuradas así (fichero
test/test_helper.rb:


  self.use_transactional_fixtures = true
  self.use_instantiated_fixtures  = false

La primera línea configura rails de manera que cada test se envuelve en una transacción, y después de ejecutar cada test se vuelve al estado anterior de la base de datos (rollback). De esta manera se evita que las fixtures se tengan que cargar antes de cada test, acelerando el proceso de pruebas.

Ajustando el segundo valor lo que se indica es que no se van a instanciar las fixtures en objetos automáticamente. Suponiendo una fixture para usuarios (usuarios.yml) como esta:


pedro:
  id: 1
  nombre: Pedro
  email: pedro@sudominio.com
  password: test
otro:
  id: 2
  nombre: Alberto
  email: alberto@sudominio.com
  password: test

Antes automáticamente se instanciaban dos objetos de tipo usuario, uno
@pedro y el otro @otro. En Rails 1.0+ no se instancian automáticamente por lo que se deben instanciar de la manera usuarios(:pedro) y usuarios(:otro) respectivamente. De nuevo esta característica permite acelerar las pruebas.

Errores con las transacciones

Bien, una vez está esto configurado y los tests adaptados para no usar los objetos instanciados, procedemos con las pruebas.

Aquí tuve otro problema, Rails empezaba a mostrar errores de que no se podían deshacer las transacciones puesto que no había ninguna iniciada. Todavía no se el porqué de esto, supongo que en sqlite3 habrá algún problema con las transacciones, así que ajustando en test/test_helper.rb así se soluciona el problema:


  self.use_transactional_fixtures = false
  ...

Pasos siguientes

Por este post ya está bien, en otros posts comentaré los problemas que tuve con:

  • Testeando autentificación de usuarios
  • Reescribiendo mi sistema de autentificación para que no cargue los usuarios completos en la sesión, sino sólo su id.
  • Errores en los nombres de los ficheros de fixtures

Escribe un comentario

*
*