unitarias rails pruebas hacer español como ruby-on-rails ruby-on-rails-3 rspec rspec2 specjour

ruby-on-rails - rails - rspec español



¿Cómo preparo la(s) base de datos de prueba para las pruebas de rspec de Rails sin ejecutar la especificación de rake? (5)

Después de una solución de problemas importante, me di cuenta de que necesitaba ejecutar la rake spec una vez (puedo abortar con control-c) antes de poder ejecutar rspec directamente (por ejemplo, en un subconjunto de nuestras especificaciones). Estamos ejecutando Rails 3.0.7 y RSpec 2.5.0.

Claramente, Rake está ejecutando algunas tareas importantes de configuración de bases de datos / código (tenemos código personalizado en los raíles del nivel raíz Rakefile y posiblemente en otros lugares).

¿Cómo puedo ejecutar las tareas de configuración / código de la base de datos de prueba de rastreos sin ejecutar la rake spec ?

Además de ser capaz de ejecutar rspec en un subconjunto de archivos, estoy usando specjour para expandir nuestras especificaciones a través de múltiples núcleos (aún no he tenido éxito al extenderlos a través de la LAN), pero veo el mismo comportamiento que para ejecutar rspec directamente: Necesito ejecutar las rake spec en cada base de datos de prueba (asumiendo dos núcleos) antes de que specjour funcione:

rake spec TEST_ENV_NUMBER=1 control-c (after tests start) rake spec TEST_ENV_NUMBER=2 control-c (after tests start) specjour

Nota: mi config / database.yml tiene esta entrada para prueba (como es común para las gemas de prueba paralelas):

test: adapter: postgresql encoding: unicode database: test<%=ENV[''TEST_ENV_NUMBER'']%> username: user password:

parallel_tests parece configurar sus bases de datos correctamente, pero muchas de nuestras especificaciones fallan.

También debo mencionar que al ejecutar specjour prepare , Postgres registra errores que no pueden encontrar las bases de datos, pero las crea (sin tablas). En una ejecución posterior, no se registran errores, pero tampoco se crean tablas. Es posible que mi problema sea simplemente un error en la prepare , así que lo informé en github.

Creo que puedo ejecutar código arbitrario en cada base de datos de prueba de Specjour::Configuration.prepare estableciendo Specjour::Configuration.prepare en .specjour / hooks.rb, por lo que si hay tareas de rake u otro código que deba ejecutar, puede funcionar allí.


En una aplicación Rails 4 con Spring-ified, mi bin/setup generalmente se aumenta para contener

puts "/n== Preparing test database ==" system "RAILS_ENV=test bin/rake db:setup"

Esto es muy similar a la respuesta de Leviathan , además de sembrar el DB de prueba, como

rake db:setup # Crea la base de datos, carga el esquema e inicializa con los datos de inicialización
(use db:reset para también soltar la base de datos primero)

Como dice el comentario, si queremos soltar primero el DB, rake db:reset simplemente hace eso.

También encuentro que esto proporciona más retroalimentación cuando se compara con el rake db:test:prepare .



Todas las soluciones proporcionadas requieren cargar el entorno Rails, que, en la mayoría de los casos, no es el comportamiento deseado debido a una sobrecarga muy grande y a una velocidad muy baja. DatabaseCleaner gema DatabaseCleaner también es bastante lenta y agrega otra dependencia a tu aplicación.

Después de meses de disgusto y disgusto gracias a razones vide supra, finalmente he encontrado la siguiente solución para ser exactamente lo que necesito. Es lindo, simple y rápido. En spec_helper.rb :

config.after :all do ActiveRecord::Base.subclasses.each(&:delete_all) end

La mejor parte de esto es: solo borrará las tablas que haya tocado efectivamente (los modelos intactos no se cargarán y, por lo tanto, no aparecerán en las subclasses , también es la razón por la que esto no funciona antes de las pruebas). Además, se ejecuta después de las pruebas, por lo que los puntos verdes (con suerte) aparecerán de inmediato.

El único inconveniente de esto es que si tiene una base de datos sucia antes de ejecutar las pruebas, no se limpiará. Pero dudo que sea un problema importante, ya que la base de datos de prueba generalmente no se toca desde pruebas externas.

Editar

Viendo que esta respuesta ha ganado algo de popularidad, quise editarla para completarla: si quieres borrar todas las tablas, incluso las que no se tocaron, deberías poder hacer algo como los "hacks" a continuación.

Hack 1 - carga previa de todos los modelos para el método de subclasses

Evalúe esto antes de llamar subclasses :

Dir[Rails.root.join("app", "models", "**", "*.rb")].each(&method(:require))

Tenga en cuenta que este método puede llevar un tiempo.

Hack 2: truncar manualmente las tablas

ActiveRecord::Base.connection.tables.keep_if{ |x| x != ''schema_migrations'' }

obtendrá todos los nombres de las tablas, con los que puede hacer algo como:

case ActiveRecord::Base.configurations[Rails.env]["adapter"] when /^mysql/, /^postgresql/ ActiveRecord::Base.connection.execute("TRUNCATE #{table_name}") when /^sqlite/ ActiveRecord::Base.connection.execute("DELETE FROM #{table_name}") ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name=''#{table_name}''") end


Tuve un problema similar al configurar el sistema de IC en el trabajo, así que desarrollé un sistema para manejarlo gradualmente. Puede que no sea la mejor solución, pero me funciona en mi situación y siempre busco mejores formas de hacer las cosas.

Tengo una base de datos de prueba que necesité configurar, pero también necesité los datos sin identificar cargados para que nuestras pruebas funcionen.

Lo básico para la resolución de problemas de tareas de rake es ejecutar rake con la opción --trace para ver qué está sucediendo debajo del capó. Cuando hice esto, descubrí que la especificación de rake en ejecución hacía una serie de cosas que podía replicar (o modificar como mejor me parecían) en una tarea de rake personalizada.

Aquí hay un ejemplo de lo que hacemos.

desc "Setup test database - drops, loads schema, migrates and seeds the test db" task :test_db_setup => [:pre_reqs] do Rails.env = ENV[''RAILS_ENV''] = ''test'' Rake::Task[''db:drop''].invoke Rake::Task[''db:create''].invoke result = capture_stdout { Rake::Task[''db:schema:load''].invoke } File.open(File.join(ENV[''CC_BUILD_ARTIFACTS''] || ''log'', ''schema-load.log''), ''w'') { |f| f.write(result) } Rake::Task[''db:seed:load''].invoke ActiveRecord::Base.establish_connection Rake::Task[''db:migrate''].invoke end

Esto es solo un ejemplo y específico para nuestra situación, por lo que deberá averiguar qué se debe hacer para configurar la prueba de configuración de bases de datos, pero es bastante fácil de determinar con la opción --trace de rake.

Además, si encuentra que la configuración de la prueba tarda demasiado (como lo hace en nuestro caso), también puede volcar la base de datos en formato .sql y hacer que la base de datos de prueba la canalice directamente a mysql para cargarla. Ahorramos varios minutos de la configuración de db de prueba de esa manera. No lo muestro aquí porque complica las cosas sustancialmente, debe generarse adecuadamente sin quedarse obsoleto, etc.

HTH


Yo recomendaría descartar su base de datos de prueba, luego volver a crearla y migrar:

bundle exec rake db:drop RAILS_ENV=test bundle exec rake db:create RAILS_ENV=test bundle exec rake db:schema:load RAILS_ENV=test

Después de estos pasos, puede ejecutar sus especificaciones:

bundle exec rspec spec

notó que:

Una solución más simple es simplemente ejecutar rake db:test:prepare

Sin embargo, si usa PostgreSQL, esto no funcionará porque el entorno de los rieles se carga, lo que abre una conexión a la base de datos. Esto hace que falle la llamada de prepare porque no se puede descartar el DB. Algo complicado