2014-05-09 12 views
7

Używam szyn 4.0.5, rspec 2.14.1, capybara 2.2.1, capybara-webkit 1.1.0 i database_cleaner 1.2.0. Widzę dziwne zachowanie w następującym teście funkcji (który symuluje użytkownika wyświetlającego komentarz do postu, umieszczonego nad ikoną w celu wyświetlenia menu i kliknięcia pozycji menu w celu usunięcia komentarza):Dlaczego dodanie "uśpienia 1" w haku po wykonaniu powoduje przejście testu Rspec/Capybara?

let(:user){create(:user)} 
let(:post){create(:post, author: user)} 
let!(:comment){create(:comment, post: post, author: user)} 

... 

it "can delete a comment" do 
    assert(page.has_css? "#comment-#{comment.id}") 
    find("#comment-#{comment.id}-controls").trigger(:mouseover) 
    find("#comment-#{comment.id} .comment-delete a").click 
    assert(page.has_no_css? "#comment-#{comment.id}") 
end 

Ten test kończy się niepowodzeniem około 80% czasu, zawsze z powodu jakiegoś rekordu pobieranego z bazy danych jako nil - Otrzymuję NoMethodError: undefined method X for nil:NilClass, dla różnych wartości X. Czasami zero jest komentarzem, który jest usuwany, czasami jest to post do którego dołączony jest komentarz, czasami jest to autor komentarza/postu.

Jeśli dodać sleep 1 do końca testu, przechodzi:

it "can delete its own comment" do 
    assert(page.has_css? "#comment-#{comment.id}") 
    find("#comment-#{comment.id}-controls").trigger(:mouseover) 
    find("#comment-#{comment.id} .comment-delete a").click 
    assert(page.has_no_css? "#comment-#{comment.id}") 
    sleep 1 
end 

przechodzi również jeśli kładę sleep 1 w bloku after.

Każdy pomysł, dlaczego dostaję te NoMethodErrors i/lub dlaczego test przechodzi, gdy śpię na sekundę po wykonaniu wszystkich prac?

+2

W jakim wierszu kodu pojawia się 'NoMethodError'? To dziwne, że ustawienie "uśpienia" na * końcu * rozwiązuje to, ale warunki występujące w Capybara są częstym problemem. –

+0

@BuckDoyle Wszystkie błędy mówią: 'Failure/Error: Nie można znaleźć pasującej linii z backtrace', a następnie odwołania do różnych metod modelu/kontrolera, które są wywoływane przez żądanie AJAX, które jest wyzwalane po usunięciu komentarza. Wygląda na to, że jest to stan wyścigowy, nie między asercją Capybara i usunięciem komentarza, ale między oderwaniem bazy danych a kodem zwrotnym, który działa po usunięciu. –

Odpowiedz

5

Podejrzewam, że jest to możliwe w aplikacji za komentarz zniknie ze strony (co jest ostatnią rzeczą jesteś twierdząc) zanim zostanie usunięte z bazy danych. Oznacza to, że test może zostać oczyszczony przed usunięciem. W takim przypadku możesz to naprawić, czekając na faktyczne usunięcie na końcu testu. Mam ten sposób wokół (a reimplementacja a method that was removed from Capybara 2 but is still sometimes necessary)

def wait_until(delay = 1) 
    seconds_waited = 0 
    while ! yield && seconds_waited < Capybara.default_wait_time 
    sleep delay 
    seconds_waited += 1 
    end 
    raise "Waited for #{Capybara.default_wait_time} seconds but condition did not become true" unless yield 
end 

więc mogę zrobić

wait_until { Comment.count == 0 } 

w testach.

Innym podejściem jest dodanie oprogramowania pośredniczącego typu Rack, które blokuje żądania wykonane po zakończeniu testu. To podejście jest opisane szczegółowo tutaj: http://www.salsify.com/blog/tearing-capybara-ajax-tests Widziałem, jak radzi sobie z wyciekiem danych w dużym zestawie specyfikacji funkcji RSpec.

+1

W rzeczywistości komentarz zawsze jest usuwany przed zniknięciem, ale zniknięcie wyzwala wywołanie zwrotne AJAX, które (jak sądzę) ściga się przy oczyszczaniu bazy danych. Podejście, które łączysz, wygląda obiecująco; Wypróbuję to. Dzięki! –

+1

Capybara.default_wait_time jest teraz przestarzałe na rzecz Capybara.default_max_wait_time – Karen

-1

https://github.com/jnicklas/capybara#asynchronous-javascript-ajax-and-friends

When working with asynchronous JavaScript, you might come across situations where you are attempting to interact with an element which is not yet present on the page. Capybara automatically deals with this by waiting for elements to appear on the page.

+2

Nie wyjaśnia to, dlaczego uśpienie na * końcu * rozwiązuje problem, po dokonaniu jakichkolwiek stwierdzeń. Dlatego poprosiłem oryginalny plakat o więcej szczegółów. –

+0

Ale mówi, że nie powinieneś używać snu. Dlaczego miałbyś celowo spowalniać testy? Kapibara radzi sobie z oczekiwaniem na elementy bardzo dobrze, jak na phoet. – Dono

Powiązane problemy