2013-01-10 21 views
8

Mam starą aplikację Railsową uaktualnioną do wersji 3.2.11, która ma wiele specyfikacji żądań napisanych przy użyciu kapibary w wersji 1.0.1 i działających przy użyciu sterownika selenu . Baza danych są czyszczone po każdym teście za pomocą database_cleaner przy użyciu strategii skracania.Aktualizacja kapibary z wersji 1.0.1 do wersji 1.1.4 powoduje, że database_cleaner łamie moją specyfikację

Chcę używać poltergeist zamiast selenu i ulepszonej kapibary od 1.0.1 do 1.1.4, aby móc korzystać z najnowszej wersji poltergeista. Tylko zmiana klejnotu kapibara (i jego zależności) spowodowała problemy z uruchomieniem moich specyfikacji.

Konsekwentnie dostaję błędy zakleszczeń z mojej bazy danych PostgreSQL w procedurze czyszczenia po każdej specyfikacji. Moja spec_helper jest dość prosty i wygląda następująco:

RSpec.configure do |config| 
    config.mock_with :rspec 

    config.use_transactional_fixtures = false 

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

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

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

Błąd pojawia się tak:

An error occurred in an after hook 
    ActiveRecord::StatementInvalid: PG::Error: ERROR: deadlock detected 
DETAIL: Process 41747 waits for AccessExclusiveLock on relation 17612 of database 16396; blocked by process 41752. 
Process 41752 waits for RowExclusiveLock on relation 17529 of database 16396; blocked by process 41747. 
HINT: See server log for query details. 
: ALTER TABLE "aaa" ENABLE TRIGGER ALL;ALTER TABLE "bbbb" ENABLE TRIGGER ALL;ALTER TABLE "ccc" ENABLE TRIGGER ALL; 
    occurred at /xxx/.bundle/gems/activerecord-3.2.11/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `async_exec' 

używam FactoryGirl do tworzenia danych testowych, ale poza tym nic specjalnego IMO.

Nie byłem w stanie dowiedzieć się, co trzyma drugi koniec zakleszczenia utworzonego przez database_cleaner. Wszelkie pomysły na zrozumienie tego są mile widziane.

Ktoś wie o jakichkolwiek zmianach między kapibarami 1.0.1 i 1.1.4, które uległy zmianie i mogły zacząć powodować te problemy?

+0

I rzeczywiście Experien przeciwnie. W moich testach miałem sporadyczne zakleszczenia, aż do przejścia na wersję 1.1.2 Kapibary 1.1.4. Niestety mój komentarz nie jest bardziej pomocny. =/ –

+0

Dobrze się cieszę, że nie jestem jedynym, który doświadcza problemów z zakleszczeniem :-) Po prostu nie rozumiem, dlaczego dwa wątki jednocześnie uzyskują dostęp do tabel w tym samym czasie. DatabaseClean powinien działać tylko po zakończeniu rzeczywistych testów ... – HakonB

+0

A może to być głupie pytanie, ale czy próbowałeś aktualizacji swojego gem DatabaseCleaner? Ponadto, FWIW Myślę, że dla nas błędy zaczęły się pojawiać dopiero po rozpoczęciu korzystania z delayed_job (mimo, że wyłączyliśmy go do testów). –

Odpowiedz

5

mam ten problem w ogórka umieszczając

sleep 0.2 

na końcu etapu (lub w przypadku „SPEC”), który wykonuje pewne rzeczy AJAX. Wyobrażam sobie, co się dzieje, że ten program do czyszczenia połączeń ogórek/rspec, podczas gdy sterownik JS wciąż czeka na odpowiedź ajax.

+0

Dla mnie. Wydaje się dziwne, że nie ma z tym więcej ludzi. –

+0

Pracowałem także dla mnie. Czy widzisz jakieś prawdziwe rozwiązanie? – morgler

+0

Działa to, ale niepotrzebnie spowalnia testowanie i może czasami zawieść. Poprawka polega na wywołaniu połączenia z API Capybara (jak has_content?) Na końcu testu. Rozwinąłem w odpowiedzi poniżej. –

5

Poprawki nie należy używać sleep, ale należy używać wyłącznie metod API Capybara, ponieważ czekają one na oczekiwane.

Poniżej linii 2 nie (jak current_path nie jest czekanie, ale linia 3 prace (jak has_selector? czeka). Link do artykułu Jonas Nicklas' poniżej wyjaśnia to dobrze.

click_on 'signup_button' # Which does an AJAX redirect to /dashboard 
assert_equal dashboard_path, current_path # This causes the deadlock error as Capybara doesn't wait. 
assert page.has_selector?("#dashboard") # This works as it causes Capybara to wait for the new page. 

http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara

+0

Jestem pewien, że to działa tylko w Capybara 2. Czy wypróbowałeś to w Capybara <2? –

1

rozwiązanie używamy jest znaleźć coś na stronie, które powinny się zmienić w odpowiedzi na pomyślne wywołanie ajax więc coś takiego:.

click_on('Save') 
expect(page).to have_content('Saved')