Después de una resolución de problemas significativa, descubrí que necesitaba ejecutar 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 / código de configuración de base de datos importantes (tenemos código personalizado en los rieles de nivel raíz Rakefile y posiblemente en otros lugares).
¿Cómo puedo ejecutar el código / tareas de configuración de la base de datos de prueba de rake sin ejecutar rake spec
?
Además de poder ejecutar rspec en un subconjunto de archivos, estoy usando specjour para difundir nuestras especificaciones en varios núcleos (todavía no he tenido éxito al difundirlas en la LAN), pero veo el mismo comportamiento que para ejecutar rspec directamente: necesito ejecutar rake spec
en cada base de datos de prueba (asumiendo dos núcleos) antes de que funcione specjour:
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:
Paralelo_tests parece configurar sus bases de datos correctamente, pero muchas de nuestras especificaciones fallan.
También debo mencionar que la ejecución specjour prepare
hace que Postgres registre 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 todo mi problema sea simplemente un error prepare
, así que lo informé en github.
Creo que puedo ejecutar código arbitrario en cada base de datos de prueba specjour configurando Specjour::Configuration.prepare
.specjour / hooks.rb, por lo que si hay tareas de rastrillo u otro código que necesito ejecutar, puede funcionar allí.
Recomendaría eliminar 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:
gerry3 señaló que:
Sin embargo, si está utilizando PostgreSQL, esto no funcionará porque el entorno de rieles se carga, lo que abre una conexión a la base de datos. Esto hace que la
prepare
llamada falle, porque la base de datos no se puede quitar. Cosa complicada.fuente
rake db:test:prepare
.rake db:test:prepare
Postgres. Debes estar viendo tu problema por alguna otra razón.RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load
rake db:test:prepare
está obsoleto en Rails 4.bundle exec rake db:drop db:create db:schema:load RAILS_ENV=test
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 una velocidad muy baja.
DatabaseCleaner
gem también es bastante lento y agrega otra dependencia a su aplicación.Después de meses de disgusto y disgusto gracias a las razones vide supra, finalmente he encontrado que la siguiente solución es exactamente lo que necesito. Es agradable, 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 de manera efectiva (los modelos intactos no se cargarán y, por lo tanto, no aparecerán
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
Dado que esta respuesta ha ganado algo de popularidad, quise editarla para que esté completa: si desea borrar todas las tablas, incluso las que no se han tocado, debería poder hacer algo como los "trucos" a continuación.
Hack 1: precarga de todos los modelos para el
subclasses
métodoEvalú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 algún tiempo.
Hack 2 - truncar las tablas manualmente
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
fuente
Parece que en Rails 4.1+, la mejor solución es simplemente agregar
ActiveRecord::Migration.maintain_test_schema!
su rails_helper despuésrequire 'rspec/rails'
.es decir, ya no tiene que preocuparse por tener que preparar la base de datos.
https://relishapp.com/rspec/rspec-rails/docs/upgrade#pending-migration-checks
fuente
En una aplicación Rails 4 con muelles,
bin/setup
normalmente mi se aumenta para contenerputs "\n== Preparing test database ==" system "RAILS_ENV=test bin/rake db:setup"
Esto es muy similar a la respuesta de leviatán , además de sembrar la base de datos de prueba, como
Como menciona el comentario, si queremos eliminar la base de datos primero, hagamos
rake db:reset
precisamente eso.También encuentro que esto proporciona más comentarios en comparación con
rake db:test:prepare
.fuente
Empecé descartando mi base de datos de prueba
rake db:drop RAILS_ENV=test
al intentar crear una nueva base de datos de prueba, encontré un problema porque mi cuenta de usuario no era la misma que la cuenta que posee las bases de datos, así que creé la base de datos en PostgreSQL.
escriba
psql
en el símbolo del sistema y luego ejecute lo siguiente para crear una base de datos de prueba que use una cuenta que no sea la suya.CREATE DATABASE your_database_name OWNER your_db_owner;
luego ejecute sus migraciones en el entorno de prueba.
rake db:migrate RAILS_ENV=test
fuente