2011-07-05 20 views
5

Estoy usando Ruby on Rails 3 y estoy escribiendo pruebas pero es demasiado lento. ¿Hay alguna buena configuración o herramientas para hacerlo más rápido?¿Cómo puedo ejecutar pruebas en RoR más rápido?

+3

Si está utilizando RSpec se puede arrancar con [Spork] (http://rubygems.org/ gems/spork) –

Respuesta

2

Como dice @eml, si está utilizando RSpec, puede usar Spork. Esto básicamente dispara el medio ambiente (que es la parte lenta) y luego lo mantiene alrededor, bifurcando cada vez que ejecuta sus especificaciones.

Para una solución más general al problema del "entorno siempre cargado" puede instalar rails-sh y ejecutar sus pruebas desde dentro del shell.

Nota al margen: Ruby 1.9.3 debería aliviar este problema ligeramente ya que se ha optimizado el tiempo de necesidad.

4

Probablemente la mayor ganancia de velocidad provenga de tener cuidado de no golpear la base de datos a menos que sea necesario. Simula objetos en lugar de buscarlos desde la base de datos, y/o (si está usando factory girl por ejemplo) use Factory.build (: stuff) en lugar de Factory (: stuff) siempre que sea posible. Solo cuando lo haya hecho debería comenzar a tratar de optimizar aún más con spork

Actualización: Personalmente, también estoy empezando a pensar que no debe volverse a colgar sobre la velocidad de sus pruebas de todos modos. Más rápido es obviamente mejor, pero a medida que una aplicación crece, el conjunto de pruebas crecerá y, por muy cuidadoso que sea, eventualmente se volverá más lento de lo que le gustaría. Voy a confiar cada vez más en la gema de prueba automática que prueba el cambio de código y funciona en segundo plano (guard-rspec hace un trabajo similar). Para cuando su aplicación llegue a las 1000 pruebas, no querrá esperar a que todo el paquete termine cada vez que realice un cambio, sin importar cuán rápido se ejecuten las pruebas.

+0

Un gran consejo. Realmente aprecio el código donde se puede decir que un desarrollador se ha ocupado de esta área. Mi única advertencia, no necesariamente insistiría en pruebas rápidas como requisito para Spork. Especialmente cuando se ejecuta un pequeño conjunto de especificaciones de selección a menudo, donde cargar el entorno de los rieles puede ser una impedancia real. –

+0

Punto justo - Supongo que realmente son caballos para los cursos - Estaba reaccionando a una de las otras respuestas que parecían sugerir que spork era una especie de bala de plata ... No creo que esto sea lo que el escritor quería, pero yo pensó que era un poco engañoso – chrispanda

2

En mi humilde opinión la principal parte de la prueba de desaceleración es la configuración predeterminada de los dispositivos. Si la configuración es (en test/test_helper.rb):

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = false 
    self.pre_loaded_fixtures = false 
    self.use_instantiated_fixtures = true 

entonces antes de cada método de prueba su base de datos de prueba se limpia de los datos antiguos, todas las mesas están ocupados, todos los registros se leen en la memoria.

Si cambia la configuración a todo lo contrario:

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = true 
    self.pre_loaded_fixtures = true 
    self.use_instantiated_fixtures = false 

continuación, la base de datos se recrea una sola vez para cada archivo de prueba, y se carga sólo los registros que realmente necesita en cada método de ensayo.

Depende del tamaño de su conjunto de datos de prueba si considera que el tiempo de creación de la base de datos de prueba es aceptable. Cuando tenía un conjunto bastante grande de datos de prueba, cargué los dispositivos solo una vez, antes de todo el conjunto de pruebas, pero ese proyecto estaba (está) en Rails 1, y lo he modificado mucho, así que no puedo decir cómo hacerlo en Rails 3 (al menos hasta que el problema comience a ser doloroso en algún proyecto nuevo;).

Hay una discusión interminable acerca de si las pruebas deberían llegar a la base de datos o no. Si crees que deberían (dado que la cooperación con la base de datos también debería probarse), entonces puedes verificar si el solo hecho de establecer estos parámetros te ayuda a ti (oa cualquiera que lea estas respuestas).

0

Intente desarrollar para que la mayoría de sus pruebas se puedan ejecutar sin necesidad de cargar todo el marco de aplicación de Rails. En su ayudante de especificaciones, obviar la carga del medio ambiente o CPER/rieles si sólo las pruebas rápidas se ejecutan, algo así como ...

# /spec/spec_helper.rb 
if RSpec.configuration.inclusion_filter[:fast] 
    # Setup required for fast tests in particular (if any) 
    # ... 
else 
    ENV["RAILS_ENV"] ||= 'test' 
    require File.expand_path("../../config/environment", __FILE__) 
    require 'rspec/rails' 

    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 
end 

RSpec.configure do |config| 
    # ... 

    unless RSpec.configuration.inclusion_filter[:fast] 
    # If you're not using ActiveRecord, or you'd prefer not to run each of your 
    # examples within a transaction, remove the following line or assign false 
    # instead of true. 
    config.use_transactional_fixtures = true 
    end 
end 

Para marcar una prueba como "rápido", añade la opción , :fast => true a su llamamiento it o a una llamada circundante describe.

Para ejecutar solo las pruebas rápidas, ejecute rspec --tag fast desde el shell de comandos.

Puede ser difícil encontrar la manera de estructurar el código para que las pruebas se puedan ejecutar por separado de Rails (y por supuesto, querrá tener pruebas funcionales y de integración que no se ejecuten por separado).

Un truco en mi arsenal es evitar escribir código directamente en un modelo ActiveRecord u otra clase similar, y prefiero escribirlo en un módulo mixin en su lugar. Puede probar el módulo mixin definiendo Sujeto a ser un objeto que se extiende por ese módulo ...

describe 'MyModule', :fast => true 
    subject{ Object.new.tap{|o| o.extend MyModule} } 

    it 'does something' do 
    # ... 
    end 
end 
Cuestiones relacionadas