Ich habe eine Feature/Integration-Spezifikation, die einen gesamten Benutzerfluss durchläuft. Am Ende dieses Benutzerflusses zeigt eine Seite in der App einige Datensätze aus meiner Postgres-Datenbank an. Wenn ich den Test selbst durchführe, passiert er. Ich kann sehen, wie es durch die verschiedenen Schritte richtig speichert, da der selen Treiber firefox öffnet: Capybara.current_driver = :selenium
. Diese Spezifikation schlägt jedoch regelmäßig, fast vorhersehbar, fehl, wenn sie nach einer Reihe von Controller-Spezifikationen ausgeführt wird. In diesen Controller Angaben die einzige interessante Sache, die ich ist tue läuft diese Login-Funktion:Flockige Tests mit DatabaseCleaner und Transaktionen. Wie zu debuggen?
module DeviseMacros
def login_user
before(:each) do
@request.env['devise.mapping'] = Devise.mappings[:user]
user = create(:user_with_active_account)
sign_in user
end
end
end
So nenne ich es wie folgt aus:
describe AwesomeController do
login_user
it 'responds with 200' do
get :new
expect(response.status).to eq 200
end
end
Wenn nach einer Controller-Spezifikation ausführen kann ich sofort sehen, dass Der Test wird fehlschlagen, da bestimmte UI-Elemente angezeigt werden sollten, abhängig davon, was in der Datenbank enthalten ist und eindeutig nicht vorhanden sind.
Meine DatabaseCleaner Strategie ist wie folgt:
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
Durch Versuch und Irrtum ich
geändertconfig.before(:each) do
DatabaseCleaner.strategy = :transaction
end
zu
config.before(:each) do
DatabaseCleaner.strategy = :truncation
end
Und walla, es geht. Natürlich dauert die Testsuite jetzt doppelt so lange.
habe ich alle meine :selenium
Tests mit js: true
um getaggt für sie verwendet, um sicherzustellen :truncation
ist aber, dass wirklich da :selenium
spielt keine Rolle, schon jene fährt. Am wichtigsten ist jedoch, dass diese Feature-Spezifikation nach diesen Controller-Spezifikationen weiterhin fehlschlägt.
Wo sonst sollte ich suchen? Wie gehe ich mit dem Debugging vor?
Die einzige andere Sache, die ich hier drin haben, die in Beziehung gesetzt werden kann, ist:
# In spec/support/shared_db_connection.rb
# https://gist.github.com/josevalim/470808
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || retrieve_connection
end
end
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
Ratschläge oder Ideen, wie es weitergehen würde mit Debugging sehr geschätzt.
Wenn Sie weitere Fragen haben, fragen Sie bitte. Danke
Update: 1. Juni 2016
Die genaue Codezeile, die den Fehler verursacht, ist:
module DeviseMacros
def login_user
before(:each) do
@request.env['devise.mapping'] = Devise.mappings[:user]
user = create(:user_with_active_account)
sign_in user # <----- THIS GUY RIGHT HERE! When removed, the ControllerSpec fails but the integration test passes.
end
end
end
So aus irgendeinem Grund scheint es, dass die DB mit diesem Controller spec schlagen (die verwendet :transaction
Strategie) wirkt sich auf die Feature-Spezifikation (die :truncation
Strategie verwendet).
Ich debattiere nur nicht die DB überhaupt in den Controller-Spezifikationen zu treffen, wenn ich versuche, einen Gerätebenutzer zu authentifizieren, was mit mir cool ist, aber ich denke, es sollte nicht so sein müssen. Irgendwelche Ideen, wie man vorgeht, wenn ich tatsächlich in der Lage sein möchte, die sign_in
Methode zu verwenden?
Danke
BTW, was passiert, wenn Sie verwenden überall die Transaktionsstrategie? Weil ich denke, dass dies der ActiveRecord-Patch ist, nicht wahr? – BoraMa
@BoraMa Danke für die Vorschläge. Wenn ': transaction' überall benutzt wird, bekomme ich viel mehr Fehler, die mit der DB zu tun haben. Ich aktualisierte mit mehr Info über die Codezeile, die das obige Problem verursacht. Irgendwelche Ideen? –
OK, ich würde auch für das Dumping dieses AR-Patches stimmen und versuchen, das Problem ohne es zu lösen. Können Sie Ihre 'sign_in' Methode posten? Übrigens erinnere ich mich vage daran, dass wir in der Vergangenheit ähnliche Probleme mit unseren Tests hatten. Am Ende haben wir die Tests auf zwei Testsuiten aufgeteilt: alle nicht JS und alle JS, und wir führen die beiden Testanzüge getrennt und ohne weitere Probleme aus. – BoraMa