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