it-swarm.com.de

schienen rspec vor allen vs vor jedem

contest_entry_spec.rb

    require 'spec_helper'

    describe ContestEntry do

      before(:all) do
        @admission=Factory(:project_admission)
        @project=Factory(:project_started, :project_type => @admission.project_type)
        @creative=Factory(:approved_creative, :creative_category => @admission.creative_category)
        @contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
      end

      context 'non-specific tests' do
        subject { @contest_entry }
        it { should belong_to(:owner).class_name('User') }
        it { should belong_to(:project) }
        it { should have_many(:entry_comments) }

        it { should validate_presence_of(:owner) }
        it { should validate_presence_of(:project) }
        it { should validate_presence_of(:entry_no) }
        it { should validate_presence_of(:title) }

      end
end

Wenn ich diese Tests durchführe, ist alles in Ordnung, aber wenn ich vor (: alle) in vor (:) wechsle, wird jeder Test fehlschlagen. Ich weiß nicht, warum es passiert?

Das ist der Fehler 

 Failure/Error: @contest_entry=Factory(:contest_entry, :design_file_name => 'bla bla bla', :owner => @creative, :project => @project)
     ActiveRecord::RecordInvalid:
       Validation Failed: User is not allowed for this type of project
60
Johnny Cash

before(:all) führt den Block einmal aus, bevor alle Beispiele ausgeführt werden.

before(:each) führt den Block einmal vor jeder Ihrer Angaben in der Datei aus

before(:all) setzt die Instanzvariablen @admission, @project, @creative, @contest_entry einmal, bevor alle it-Blöcke ausgeführt werden.

:before(:each) setzt jedoch die Instanzvariablen im Vorblock jedes Mal zurück, wenn ein it-Block ausgeführt wird. 

Es ist eine subtile Unterscheidung, aber wichtig

nochmal, 

before(:all)
#before block is run
it { should belong_to(:owner).class_name('User') }
it { should belong_to(:project) }
it { should have_many(:entry_comments) }

it { should validate_presence_of(:owner) }
it { should validate_presence_of(:project) }
it { should validate_presence_of(:entry_no) }
it { should validate_presence_of(:title) }

before(:each)
# before block
it { should belong_to(:owner).class_name('User') }
# before block
it { should belong_to(:project) }
# before block
it { should have_many(:entry_comments) }
# before block

# before block
it { should validate_presence_of(:owner) }
# before block
it { should validate_presence_of(:project) }
# before block
it { should validate_presence_of(:entry_no) }
# before block
it { should validate_presence_of(:title) }
96
fontno

Ein wichtiges Detail von before :all ist, dass es nicht DB transactional ist. Das heißt, alles innerhalb der before :all bleibt in der Datenbank bestehen und Sie müssen die after :all-Methode manuell abbauen. 

Implikationen bedeuten, dass nach Abschluss der Testsuiten die Änderungen nicht für spätere Tests bereit sind. Dies kann zu komplizierten Fehlern und Problemen mit der Kreuzkontamination von Daten führen. I.e, Wenn eine Ausnahme ausgelöst wird, wird der after :all-Callback nicht aufgerufen.

before: eachist jedoch eine DB-Transaktion.

Ein schneller Test zur Demonstration:

1. Kürzen Sie die entsprechende DB-Tabelle und versuchen Sie es dann.

  before :all do
    @user = Fabricate(:user, name: 'Yolo')
  end

2. Beobachten Sie anschließend die Datenbank das Modell bleibt erhalten

after :all ist erforderlich. Wenn jedoch eine Ausnahme in Ihrem Test auftritt, tritt dieser Rückruf nicht auf, da der Fluss unterbrochen wurde. Die Datenbank bleibt in einem unbekannten Zustand, was insbesondere bei CI/CD-Umgebungen und automatisierten Tests problematisch sein kann.

3. probiere es jetzt aus,

  before :each do
    @user = Fabricate(:user, name: 'Yolo')
  end

4. Nun ist die Datenbank frei von Daten, nachdem die Testsuite abgeschlossen ist. Viel besser und hinterlässt nach dem Testlauf einen einheitlichen Zustand.

Kurz gesagt, before :each ist wahrscheinlich das, was Sie wollen. Ihre Tests laufen etwas langsamer, aber es lohnt sich.

Detail hier: https://relishapp.com/rspec/rspec-Rails/docs/transactions Siehe: Data created in before(:all) are not rolled back

Hoffe das hilft einem anderen müden Reisenden.

20
wired00

before(:all), um sicherzustellen, dass die Beispielbenutzer vor allen Tests im Block einmal erstellt werden. Dies ist eine Optimierung der Geschwindigkeit.

3
Jazib Bashir

Zu beachten ist vor der Verwendung standardmäßig (: each), auch in before (: all) ist die Controller-Instanz nicht festgelegt, so dass die Controller-Methoden wie request nicht verwendet werden.

0
shiva kumar