2011-03-21 9 views
14

Me gustaría aumentar la velocidad de mis pruebas.Rspec, pepino: mejor estrategia de limpieza de base de datos de velocidad

  1. ¿Debo usar use_transactional_fixtures o ir con el database_cleaner joya?
  2. ¿Qué estrategia de database_cleaner es la mejor? Noté que después de la migración de :truncation a :transaction ¡mis más de 800 ejemplos se ejecutan aproximadamente 4 veces más rápido!
  3. ¿Debo apagar use_transactional_fixtures cuando uso database_cleaner :transaction?
  4. ¿Es cierto que la mejor estrategia para rack_test es :transaction?
  5. ¿Cuáles son las mejores prácticas para cambiar la estrategia sobre la marcha de :transaction a :truncation cuando usa selenio o akephalos?

P.S. Mysql, Rails 3, Rspec2, pepino

P.P.S. Sé sobre spork y parallel_test y los uso. Pero son offtópicos. Por ejemplo, Spork ahorra alrededor de 15-20 segundos en toda la suite, pero cambiar de :transaction a :truncation aumenta drásticamente el tiempo de ejecución de 3.5 a 13.5 minutos (diferencia de 10 minutos).

+0

Interesante: [Fixtures v. Factories - ¿No podemos todos nos llevamos bien?] (Http://www.metabates.com/2010/08/15/fixtures-v-factories-cant-we-all- just-get-along /) – Zabba

Respuesta

-1

¿Has utilizado Spork? Mejora en gran medida la velocidad.

+1

Sí, uso spork. Pero está fuera del tema. Spork ahorra ~ 15 seg. en el comienzo. Pero cambiar la estrategia ahorra 10 min. para mi suite de pruebas ... – petRUShka

4

El uso de dispositivos transaccionales será más rápido ya que el DBMS no confirma los cambios (y por lo tanto, no ocurre un IO pesado restableciendo la base de datos entre pruebas) pero como usted sabe no siempre funcionará.

Hemos tenido cierto éxito al utilizar las bases de datos SQLite en memoria en el entorno de prueba, por lo que las pruebas se ejecutan súper rápido mientras se desactivan los dispositivos transaccionales. Esta opción también está disponible para MySQL (use: opciones para establecer "ENGINE = MEMORY") pero nunca lo he hecho personalmente y si busca, encontrará algunos hilos sobre las advertencias involucradas. Puede valer la pena mirar. Sin embargo, dependiendo de su metodología de prueba, puede no ser aceptable usar un motor DB diferente.

Sugiero que habilite dispositivos transaccionales y use la gema DatabaseCleaner para deshabilitar selectivamente dispositivos transaccionales por grupo de ejemplo. No puedo decir que lo haya intentado, pero como no tenías ninguna respuesta, pensé que cualquier cosa podría ayudarte.

before(:all) do 
    DatabaseCleaner.strategy = :transaction 
    DatabaseCleaner.clean_with(:truncation) 
end 

before(:each) do 
    DatabaseCleaner.start 
end 

after(:each) do 
    DatabaseCleaner.clean 
end 

Si fuera yo me factor esto a cabo en un ayudante y lo llaman como una macro de una línea de cada grupo de ejemplo de que las necesidades transaccionales accesorios apagados.

Parece que realmente debería haber una mejor manera, sin embargo .... la mejor de las suertes.

+0

Esto no aborda las pruebas de selenio que no funcionarán con las transacciones. A veces necesitas tanto truncamiento como trasacción. –

6

1., 2. 4. &, Debe utilizar transacciones (ya sea con o use_transactional_fixtures transacciones apoyo de la gema database_cleaner) si está utilizando el motor por defecto de capibara, rack_test. Como ha notado, el uso de transacciones es sustancialmente más rápido que el uso de una estrategia de truncamiento. Sin embargo, cuando las escrituras de la base de datos pueden pasar por diferentes hilos (como con el selenio), las transacciones no funcionarán. Por lo tanto, deberá usar el truncamiento (o forzar todo para pasar por un hilo de base de datos, otra opción).

3. Sí, debe desactivar use_transactional_fixtures al usar la gema database_cleaner dado que la gema admite transacciones nativamente. Si solo necesita transacciones, simplemente use use_transactional_fixtures y nunca cargue la gema de database_cleaner.

5. El siguiente código cambiará entre :transaction y :truncation sobre la marcha. (Probado con rspec, capibara, rails3.) ​​

Características Esto debería darte lo mejor de ambos mundos. La velocidad de rack_test cuando no necesita probar cosas de javascript y la flexibilidad de selenium cuando lo hace.

También este código se encarga de repoblar los datos de la semilla en los casos en que sea necesario (este método supone que use seeds.rb para cargar sus datos de inicialización, como es la convención actual).

Agregue el siguiente código a spec_helper.

config.use_transactional_fixtures = false 
RSpec.configure do |config| 
    config.before(:suite) do 
    require "#{Rails.root}/db/seeds.rb" 
    end 

    config.before :each do 
    if Capybara.current_driver == :rack_test 
     DatabaseCleaner.strategy = :transaction 
    else 
     DatabaseCleaner.strategy = :truncation 
    end 
    DatabaseCleaner.start 
    end 
    config.after(:each) do 
    if Capybara.current_driver == :rack_test 
     DatabaseCleaner.clean 
    else 
     DatabaseCleaner.clean 
     load "#{Rails.root}/db/seeds.rb" 
    end 
    end 
end 

Gracias Jo Liss por señalar el camino.

PS: La manera de conectar los conductores sobre la marcha

La solución anterior se supone que ya sabe cómo cambiar los conductores sobre la marcha. En caso de que algunos de los que vienen aquí no lo hagan, así es cómo:

Como arriba, supongamos que normalmente usará el driver de capybara predeterminado rack_test, pero necesita usar selenio para probar algunas cosas de Ajaxy. Cuando desee utilizar el controlador de selenio, use :js => true o @javascript para Rspec o pepino, respectivamente. Por ejemplo:

ejemplo Rspec: ejemplo

describe "something Ajaxy", :js => true do 

Pepino:

@javascript 
Scenario: do something Ajaxy 
1
RSpec.configure do |config| 

    config.before(:suite) do 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

    config.before(:each, :js => true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
    DatabaseCleaner.start 
    end 

    config.after(:each) do 
    DatabaseCleaner.clean 
    end 

end 

Esto es de Avdi Grimm's post sobre limpiador de base de datos y Rspec. El análisis paso a paso del código está en el artículo.

+0

Esta es una configuración fantástica para equilibrar el compromiso de las pruebas unitarias tradicionales (donde: la transacción se debe usar porque es muy rápido) y las pruebas de integración (donde: el truncamiento se debe usar para respaldar las pruebas de múltiples pasos/múltiples páginas) – brycemcd

Cuestiones relacionadas