RSpec let protiv before
U RSpec-u postoje dva različita načina za pisanje SUVIH testova, koristeći before ili let . Njihova svrha je da kreiraju promenljive koje su uobičajene u testovima. U ovom postu ćemo istražiti razlike između pre i let i objasniti zašto rubi zajednica preferira let .
let
Neka kreiramo lenjo procenjene lokalne promenljive. To znači da se let() ne vrednuje dok se metoda koju definiše ne pokrene prvi put. SUŠI specifikaciju i čini je čitljivijom.
$count = 0
describe "let" do
let(:count) { $count += 1 }
it "stores the value" do
expect(count).to eq(1)
expect(count).to eq(1)
end
it "is not cached across examples" do
expect(count).to eq(2)
end
end
Neka se ne koristi za lokalne promenljive, koje se moraju sačuvati u bazi podataka, jer one neće biti sačuvane u bazi podataka ako na njih već nije referenca. U ovom slučaju, trebalo bi da koristite let! ili before blokove.
Testovi koje kreiramo rade se pomoću RSpec-a i Capibare.
Takođe, nikada nemojte imati blok let unutar bloka pre bloka, ovo je ono što je dozvoljeno! je stvoren za!
let!
Za razliku od let, možete koristiti let! da prisili na pozivanje metode pre svakog primera . To znači da će se, čak i ako niste pozvali pomoćnu metodu unutar primera, pozvati pre nego što se vaš primer pokrene.
$count = 0
describe "let!" do
invocation_order = []
let!(:count) do
invocation_order << :let!
$count += 1
end
it "calls the helper method in a before hook" do
invocation_order << :example
expect(invocation_order).to eq([:let!, :example])
expect(count).to eq(1)
end
end
Kao i kod blokova let, ako je višestruko let! blokovi su definisani sa istim imenom, izvršiće se najnoviji. Suštinska razlika je u tome što let! blokovi će se izvršiti više puta ako se koriste na ovaj način, dok će se blok let izvršiti samo poslednji put.
before(:each)
before(:each) blok će se pokrenuti pre svakog primera, čak i ako primer ne koristi nijednu promenljivu instance definisanu u bloku. Ovo može primetno usporiti podešavanje promenljivih instance.
class User
def tests
@tests ||= []
end
end
describe User do
before(:each) do
@user = User.new
end
describe "initialized in before(:each)" do
it "has 0 tests" do
@user.should have(0).tests
end
it "can accept new tests" do
@user.tests << Object.new
end
it "does not share state across examples" do
@user.should have(0).tests
end
end
end
U skoro svakoj situaciji je bolje koristiti let pre before blokova. U zavisnosti od vaših ličnih preferencija koje biste mogli da koristite pre blokade kada:
- Postoji razumna količina promenljivih.
- Postoje promenljive na koje ne treba direktno upućivati, ali su obavezne.
- Postoji mnogo naredbi koje treba izvršiti, jer je njegova sintaksa jasnija kada se radi o mnogim naredbama.
- Stvaranje podsmeha.
Pokušajte i napravite sopstveni test modela ili kontrolera !
before(:all)
Ovaj blok se izvršava samo jednom, pre svih primera u grupi. Postoje određene situacije koje mogu smanjiti izvršenje i napor.
class User
def tests
@tests ||= []
end
end
describe User do
before(:all) do
@user = User.new
end
describe "initialized in before(:all)" do
it "has 0 tests" do
@user.should have(0).tests
end
it "can get accept new tests" do
@user.tests << Object.new
end
it "shares state across examples" do
@user.should have(1).tests
end
end
end
Korišćenje before(:all) u RSpec-u će vam stvoriti mnogo problema ukoliko ne znate šta radite! Radi izvan transakcija, tako da će se ovde stvoreni podaci preliti u druge specifikacije.
Zaključak
Let blokovi donesu više na sto nego before blokovi. Sve zavisi od toga šta i kako treba da učinite da RSpec testovi rade ili razmislite o korišćenju FactoryGirl za kreiranje podataka.
Pored toga što su sporiji, jedan od glavnih problema sa before blokovima je taj što pravopisne greške mogu dovesti do grešaka i lažnih pozitivnih rezultata, omogućavajući određenim vrstama testova da prođu kada ne bi trebalo.
before(:each) do
@user = User.find(username: "kolosek")
@user.logout
end
it "should log the user out" do
expect(@usr).to be_nil
end
Budući da @usr nije prethodno definisan, test će proći, @usr je podrazumevano nula. Isti test koji koristi let podigao bi NameError jer @usr nije definisan.
Nadam se da će vam ovo pomoći da bolje razumete razlike između blokova let i before.
Hvala vam za čitanje!
Pratite našu prugu pretplatom na naš bilten! Znamo put!