Ich verwende Rails 4.0.5, rspec 2.14.1, Capybara 2.2.1, Capybara-Webkit 1.1.0 und database_cleaner 1.2.0. Ich sehe ein merkwürdiges Verhalten beim folgenden Funktionstest (der simuliert, dass ein Benutzer einen Kommentar zu einem Beitrag anzeigt, über ein Symbol schwebt, um ein Menü anzuzeigen, und auf einen Menüeintrag klickt, um den Kommentar zu löschen):Warum führt das Hinzufügen von "sleep 1" in einem after hook dazu, dass dieser Rspec/Capybara-Test bestanden wird?
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
Dieser Test schlägt ungefähr 80% der Zeit fehl, immer weil ein Datensatz aus der Datenbank als nil
- ich bekomme NoMethodError: undefined method X for nil:NilClass
, für verschiedene Werte von X abgerufen wird. Manchmal ist der Nullpunkt der Kommentar, der gelöscht wird, manchmal ist es der Beitrag dass der Kommentar angehängt ist, manchmal ist es der Autor des Kommentars/Beitrags.
Wenn ich sleep 1
bis zum Ende des Tests hinzufügen, es passiert:
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
Es geht auch, wenn ich sleep 1
in einem Block after
setzen.
Irgendeine Idee, warum ich diese NoMethodErrors bekomme, und/oder warum der Test bestanden wird, wenn ich ihn für eine Sekunde schlafen lasse, nachdem alle Arbeit erledigt ist?
Welche Codezeile ist der 'NoMethodError'-Ursprung? Es ist komisch, wenn man 'sleep' am * Ende * behebt, aber Capybara Race Conditions sind ein häufiges Problem. –
@BuckDoyle Alle Fehler sagen 'Fehler/Fehler: Es konnte keine übereinstimmende Zeile aus Backtrace gefunden werden ', gefolgt von Verweisen auf verschiedene Model/Controller-Methoden, die von einer AJAX-Anfrage aufgerufen werden, die ausgelöst wird, wenn ein Kommentar gelöscht wird. Es sieht so aus, als wäre es eine Race-Bedingung, nicht zwischen der Capybara-Assertion und der Kommentarlöschung, sondern zwischen dem Datenbank-Teardown und dem Callback-Code, der nach dem Löschen ausgeführt wird. –