2013-05-17 29 views
51

ray rspec trước khi tất cả vs trước mỗi 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 

Khi tôi chạy các bài kiểm tra mọi thứ đều okey nhưng nếu tôi thay đổi trước (: tất cả) để trước (: mỗi) mỗi thử nghiệm sẽ được thất bại Tôi không biết tại sao nó lại xảy ra?

Đây là lỗi

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 

Trả lời

85

before(:all) chạy khối một thời gian trước khi tất cả các ví dụ được chạy.

before(:each) chạy khối một lần trước mỗi thông số kỹ thuật của bạn trong file

before(:all) cài đặt các biến dụ @admission, @project, @creative, @contest_entry một thời gian trước khi tất cả các it khối đang chạy.

Tuy nhiên, :before(:each) đặt lại các biến mẫu trong khối trước mỗi khi một khối it được chạy.

nó một sự phân biệt tinh tế nhưng quan trọng

một lần nữa,

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) } 
+0

Hãy cho tôi biết nếu bạn đặt câu hỏi về bất cứ điều gì. vui lòng giúp đỡ – fontno

3

before(:all), đảm bảo rằng những người sử dụng mẫu được tạo ra một lần, trước khi tất cả các bài kiểm tra trong khối. Đây là một tối ưu hóa cho tốc độ.

14

Một trong những chi tiết quan trọng nhất của before :all là nó là không DB transactional. Tức là, bất cứ điều gì trong số before :all vẫn tồn tại với db và bạn phải tự rách theo phương pháp after :all. Ý nghĩa có nghĩa là sau khi các bộ thử nghiệm đã hoàn thành, các thay đổi không được hoàn nguyên sẵn sàng cho các thử nghiệm tiếp theo. Điều này có thể dẫn đến các lỗi và vấn đề phức tạp với sự lây nhiễm chéo dữ liệu giữa các thử nghiệm. Hãy nhớ rằng, nếu một ngoại lệ được ném, gọi lại after :all không được gọi.

Một test nhanh để chứng minh:

1. Truncate bảng DB thích hợp của bạn sau đó thử này,

before :all do 
    @user = Fabricate(:user, name: 'Happy Fun Pants') 
    end 

2. Quan sát cơ sở dữ liệu sau đó, bạn sẽ thấy mô hình vẫn còn tồn tại!? Điều này là do bạn phải bao gồm after :all, nhưng một lần nữa nếu một ngoại lệ xảy ra trong thử nghiệm của bạn, gọi lại này sẽ không xảy ra! Bất kỳ thử nghiệm nào trong tương lai sẽ chạy với một trạng thái DB không chắc chắn.

3. bây giờ cố gắng này,

before :each do 
    @user = Fabricate(:user, name: 'Happy Fun Pants') 
    end 

4. Bây giờ cơ sở dữ liệu vẫn không có dữ liệu sau khi các bộ kiểm tra hoàn tất. Không tốt với các thiết lập CI/CD.

Lỗi phức tạp có thể phát sinh nếu thử nghiệm ném một ngoại lệ và không hoàn thành trong số 100 (ngăn toàn bộ bộ thử nghiệm của bạn hoàn thành). Cơ sở dữ liệu sẽ bị bỏ lại ở trạng thái không xác định.

Tóm lại, before :each, có lẽ là những gì bạn muốn. Thử nghiệm của bạn sẽ chạy chậm hơn một chút, nhưng đáng giá.

chi tiết ở đây: https://relishapp.com/rspec/rspec-rails/docs/transactions Xem: Data created in before(:all) are not rolled back

Hy vọng rằng sẽ giúp một du khách mệt mỏi.

+0

Mẹo này giúp tiết kiệm thời gian của tôi! Chỉ cần viết trước (trước) –

Các vấn đề liên quan