2011-07-05 12 views
5

Używam Ruby on Rails 3 i pisania testów, ale jest zbyt wolny. Czy jest jakiś dobry konfigurator lub narzędzia, aby przyspieszyć?Jak mogę szybciej uruchomić testy RoR?

+3

Jeśli używasz rspec można bootstrap z [Spork] (http://rubygems.org/ gems/spork) –

Odpowiedz

2

As @eml mówi, że jeśli używasz RSpec, możesz użyć Spork. To w zasadzie podpala środowisko (co jest wolną częścią), a następnie utrzymuje je w pobliżu, rozwidlając za każdym razem, gdy uruchamiasz swoją specyfikację.

Aby uzyskać bardziej ogólne rozwiązanie problemu "środowisko zawsze ładowane", można zainstalować rails-sh i uruchomić testy z poziomu powłoki.

Nota boczna: Rubin 1.9.3 powinien nieco złagodzić ten problem, ponieważ wymagany czas został zoptymalizowany.

4

Prawdopodobnie największy wzrost prędkości wynika z ostrożności, aby nie trafić do bazy danych, chyba że jest to konieczne. Naśladuj obiekty, zamiast pobierać je z bazy danych i/lub (jeśli używasz np. Dziewczyny z fabryki), użyj Factory.build (: stuff) zamiast Factory (: stuff), gdy tylko jest to możliwe. Tylko wtedy, gdy masz zrobić, że należy rozpocząć próby do dalszej optymalizacji z Spork

Update: Osobiście, ja też zaczynam myśleć, że nie powinno się stać, aby odłożył o szybkości testów anyway. Szybciej jest oczywiście lepiej, ale w miarę jak aplikacja rośnie, zestaw testów będzie rósł, a jakkolwiek będziesz ostrożny, w końcu stanie się wolniejszy, niż byś chciał. Coraz częściej polegam na autotestu, który testuje zmiany kodu i działa w tle (guard-rspec wykonuje podobną pracę). Do czasu, gdy Twoja aplikacja osiągnie 1000 testów, nie będziesz chciał czekać, aż cały pakiet zakończy się za każdym razem, gdy dokonasz zmiany, jakkolwiek szybko przebiegną testy.

+0

Świetna rada. Naprawdę doceniam kod, w którym można powiedzieć, że deweloper zajął się tą sprawą. Moje jedyne zastrzeżenie, niekoniecznie domagam się szybkich testów, które są niezbędne dla Sporka. Zwłaszcza podczas wykonywania małego zestawu wybranych specyfikacji często, gdy ładowanie środowiska szyn może być rzeczywistą impedancją. –

+0

Fair point - Myślę, że to naprawdę konie na kursy - zareagowałem na jedną z innych odpowiedzi, które zdawały się sugerować, że spork to jakaś srebrna kula ... Nie sądzę, że to jest to, co zamierzał pisarz, ale ja pomyślałem, że to było trochę mylące – chrispanda

2

IMHO główna część spowalniająca testowania to domyślna konfiguracja urządzeń. Jeśli konfiguracja jest (w test/test_helper.rb):

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

następnie przed każdym badaniem metoda baza danych test jest oczyszczony ze starych danych, wszystkie stoliki są wypełniane, wszystkie rekordy są wczytywane do pamięci.

Jeśli zmienisz ustawienia na przeciwny:

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

następnie baza danych zostanie odtworzony tylko raz dla każdego pliku testowego i załadować tylko te rekordy, których naprawdę potrzebujesz w każdej metodzie testowej.

To zależy od wielkości twojego testowego zestawu danych, czy uważasz, że czas utworzenia bazy testowej jest akceptowalny. Kiedy miałem dość duży zbiór danych testowych, ładowałem urządzenia tylko raz, przed całym pakietem testów, ale ten projekt był (jest) w Rails 1, i mocno go zmodyfikowałem, więc nie mogę powiedzieć, jak to zrobić w Rails 3 (przynajmniej dopóki problem nie zacznie boleć w jakimś nowym projekcie;).

Istnieje niekończąca się dyskusja, czy testy powinny trafić do bazy danych, czy nie. Jeśli uważasz, że powinni (ponieważ baza danych powinna również zostać przetestowana), możesz sprawdzić, czy tylko ustawienie tych parametrów pomaga (lub każdemu, kto czyta te odpowiedzi).

0

Staraj się rozwijać, aby większość testów można było wykonać bez konieczności ładowania całego środowiska aplikacji Rails. W swojej specyfikacji pomocnika, pomiń ładowanie środowisko lub rpec/szyny jeśli tylko szybki testy są wykonywane, coś jak ...

# /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 

Aby oznaczyć test jako „szybki”, dodaj opcję , :fast => true jego it rozmowy lub do otaczającego wywołania describe.

Aby uruchomić tylko szybkie testy, wykonaj polecenie rspec --tag fast z powłoki poleceń.

Trudno jest wymyślić sposób ustrukturyzowania kodu tak, aby testy mogły być uruchamiane oddzielnie od Railsów (i, oczywiście, nadal będziesz chciał mieć testy funkcjonalne i integracyjne, które nie są uruchamiane osobno).

Jedna sztuczka w moim arsenale polega na tym, że należy unikać bezpośredniego pisania kodu w modelu ActiveRecord lub innej takiej klasie, a zamiast tego wolę pisać go na module mixin. Można przetestować moduł wstawionej przez zdefiniowanie zastrzeżeniem być obiekt, który jest przedłużony przez tego modułu ...

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

    it 'does something' do 
    # ... 
    end 
end 
Powiązane problemy