之前所有vs之前的轨道rspec
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
当我运行这些testing时,所有的东西都是okey,但是如果我之前更改(:all)到之前(:each),每个testing都会失败。我不知道为什么会发生这种情况?
这是错误
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
before(:all)
在所有示例运行之前运行一次该块。
before(:each)
在文件中的每个规范之前运行一次该块
before(:all)
在所有块运行之前一次设置实例variables@admission, @project, @creative, @contest_entry
。
但是:before(:each)
每次运行一个块时都会重置before块中的实例variables。
它是一个微妙的区别,但重要的
再次,
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) }
before :all
最重要的细节之一before :all
这一切都不是数据库transactional
。 也就是说, before :all
任何东西before :all
持续到db,而且你必须在after :all
方法中手动拆卸。 含义意味着在testing套件完成后,更改不会恢复为下一个testing准备就绪。 这可能会导致错误和testing之间数据交叉污染的问题。 请记住,如果抛出exceptionafter :all
callback不被调用。
一个快速testing来演示:
1.截断你适当的数据库表,然后试试这个,
before :all do @user = Fabricate(:user, name: 'Happy Fun Pants') end
2.之后观察数据库,您会注意到模型仍然存在 ! 这是因为你必须包括after :all
,但是如果在你的testing中发生exception,这个callback将不会发生! 任何未来的testing现在都会针对不确定的DB状态运行。
3.现在试试这个,
before :each do @user = Fabricate(:user, name: 'Happy Fun Pants') end
4.testing套件完成后,数据库仍然没有数据 。 CI / CD设置不好。
如果一个testing抛出一个exception并且不能在100个之内完成(防止你的整个testing套件完成),那么可能会出现一些卷积错误。 数据库将处于未知状态。
总之, before :each
,可能都是你想要的。 你的testing会稍微慢一些,但应该是值得的。
详细信息在这里: https : //relishapp.com/rspec/rspec-rails/docs/transactions请参阅: Data created in before(:all) are not rolled back
希望能帮助另一个疲惫的旅行者。
before(:all)
,这确保样本用户在块中的所有testing之前创build一次。 这是速度的优化。