Rails Rspec Suite出现故障,但单独运行时会通过

时间:2014-08-28 06:22:21

标签: ruby-on-rails ruby-on-rails-4 rspec

事实:

  1. 运行我的整套规范将导致610个规格中的21个一致错误。
  2. 如果我运行任何单独的spec文件(例如:messages_controller_spec.rb),它们都会通过。
  3. 如果我单独运行任何失败的规格,它们都会通过。
  4. 这些错误主要是ActionMailer失败,但有些错误。 一个令人困惑的方面是某些规范失败,因为数据库中有一个额外的行比预期的要多,而其他的则因为行数少于预期而失败。也就是说,如果它是一个清理或缓存问题,它似乎应该是一个或多一个。

    我目前通过内联运行Rails 4.1.1,Ruby 2.0.0p451,Rspec 2.14.8,Sidekiq!

    Gemfile(用于测试)

    group :development, :test do
      gem 'better_errors'
      gem 'binding_of_caller'
      gem 'faker'
      gem 'guard-rspec'
      gem 'pry'
      gem 'rspec-rails'
      gem 'spork-rails'
      gem 'sqlite3'
      gem 'thin'
    end
    
    group :test do
      gem 'capybara'
      gem 'capybara-email'
      gem 'capybara-webkit'
      gem 'database_cleaner'
      gem 'fabrication'
      gem 'launchy'
      gem 'selenium-webdriver'
      gem 'shoulda-matchers'
      gem 'webmock'
      gem 'vcr'
    end
    

    请注意,我已经检查了十几个类似的问题,这些问题无法解决这个问题。所以,澄清一下:

    1. 我没有使用ARGV
    2. 我之前没有使用过(:all) - 我之前使用过:(每个)。
    3. 我在套件和套件之前尝试了Rails.cache.clear :每个规格。
    4. 我将数据库清理器设置为:截断所有清理(更慢,但结果更好:事务 - 使用:transaction重新加载更新值时出现问题)
    5. 为方便起见,可能有一些例子会有所帮助:

      scheduler_spec.rb(显示整个套件运行时测试失败)

      require 'spec_helper'
      require 'rake'
      require 'sidekiq/testing'
      Sidekiq::Testing.inline!
      
      describe "scheduler", :vcr do
        describe ":wipe_abandoned_images" do
          let!(:abandoned_old_image)   { Fabricate(:image) }
          let!(:abandoned_young_image) { Fabricate(:image) }
          let!(:adopted_image)         { Fabricate(:image) }
          let(:run_cleaner) do
            Rake::Task[:wipe_abandoned_images].reenable
            Rake.application.invoke_task :wipe_abandoned_images
          end
      
        before do
            abandoned_young_image.update_columns(listing_id: nil, updated_at: 6.days.ago)
            abandoned_old_image.update_columns(  listing_id: nil, updated_at: 9.days.ago)
            Rake.application.rake_require 'tasks/scheduler'
            Rake::Task.define_task(:environment) #Stub env. Rspec runs the App, so dont want Rake to run it again.
        end
      
        context "for claimed images" do
            it "leaves the image" do
              adopted_image_id = adopted_image.id
              run_cleaner
                expect(Image.all.count                ).to eq(2)
                expect(Image.find(adopted_image_id) ).to be_present
            end
          end
        end
      end
      

      请注意,我正在使用Sidekiq的内联版!测试先前应用程序的配置,取得了良好的成功。没有这个问题。

      forgot_passwords_controller_spec.rb(显示整个套件运行时测试失败)

      require 'spec_helper'
      require 'sidekiq/testing'
      Sidekiq::Testing.inline!
      
      describe ForgotPasswordsController do
        let!(:jen) { Fabricate(:user, email: 'jen@example.com') }
      
        describe "POST create" do
          context "with valid email provided" do
            before { post :create, email: 'jen@example.com' }
            after do
              ActionMailer::Base.deliveries.clear
              Sidekiq::Worker.clear_all
            end
      
            it 'sends the reset email to the users provided email' do
              expect(ActionMailer::Base.deliveries.count).to eq(1)
            end
          end
        end
      end
      

      以下以各种方式运行规范时会发生什么:

      ForgotPasswordsController规范通过SublimeText2中的RubyTest插件传递

        

      2014-08-28T03:42:43Z 32968 TID-ov5g65p44信息:Sidekiq客户端   redis options {} ...........完成0.95479秒11个例子,   0失败随机种子40226 [完成5.8s]

      调度程序测试通过SublimeText2中的RubyTest传递

        

      。向用户发出邀请...完成。 。出来   用户邀请...完成。 ..扫视服务器以供放弃   图片... 2014-08-28T01:49:02Z 32426 TID-owjt9ggh8信息:Sidekiq   客户端使用redis选项{}完成。 。放弃服务器   图像......完成了。 。扫描服务器以获取废弃的图像......完成。   

           

      在1.52秒内完成7个例子,0个失败用种子随机化   37996 [在8.6s完成]

      测试通过控制台中的rspec传递 $ rspec ./spec/lib/tasks/scheduler_spec.rb

        

      。向用户发出邀请...完成。 。出来   用户邀请...完成。 ..扫视服务器以供放弃   图片... 2014-08-28T02:14:43Z 32456 TID-ouiui9g8c信息:Sidekiq   客户端使用redis选项{}完成。 。放弃服务器   图像......完成了。 。扫描服务器以获取废弃的图像......完成。   

           

      在1.32秒内完成7个例子,0个失败用种子随机化   19172

      运行整套Rspec 时测试失败 如果单独运行或作为spec文件来运行,这些失败将会通过。 $ rspec

        

      完成49.71秒610例,21次失败,10次待决

      失败的例子:

      有时会有额外的值

        

      13)scheduler:wipe_abandoned_images,用于1下的废弃图像   一周老叶子的形象        失败/错误:期望(Image.all.count).to eq(2)

         expected: 2
              got: 3
      
         (compared using ==)
       # ./spec/lib/tasks/scheduler_spec.rb:78:in `block (4 levels) in <top (required)>'
      

      有时会丢失或未加载值

        

      18)ForgotPasswordsController使用提供的有效电子邮件创建POST   将重置电子邮件发送给用户提供的电子邮件        失败/错误:期望(ActionMailer :: Base.deliveries.count).to eq(1)

         expected: 1
              got: 0
      
         (compared using ==)
       # ./spec/controllers/forgot_passwords_controller_spec.rb:22:in `block (4 levels) in <top (required)>'
      

      以下是失败列表

      rspec ./spec/controllers/messages_controller_spec.rb:161 # MessagesController POST create message about listing to user from guest with valid information with EXISTING, UN-confirmed guest with EXPIRED token sends another confirmation email with link to the guest
      rspec ./spec/controllers/messages_controller_spec.rb:114 # MessagesController POST create message about listing to user from guest with valid information with NEW, UN-confirmed, and valid guest email sends an invitation for the guest to be put on safe-email list
      rspec ./spec/controllers/invitations_controller_spec.rb:30 # InvitationsController POST create with valid email & available invitations sends an email
      rspec ./spec/controllers/invitations_controller_spec.rb:33 # InvitationsController POST create with valid email & available invitations sends an email to the recipient_email address
      rspec ./spec/controllers/users_controller_spec.rb:161 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends the email to the registering user
      rspec ./spec/controllers/users_controller_spec.rb:158 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends the email
      rspec ./spec/controllers/users_controller_spec.rb:164 # UsersController POST create with invitation token in params with valid token & input confirmation email sending sends an email with a confirmation link in the body
      rspec ./spec/controllers/users_controller_spec.rb:354 # UsersController GET confirm_with_token with valid token has a welcome message in the email
      rspec ./spec/controllers/users_controller_spec.rb:348 # UsersController GET confirm_with_token with valid token sends a welcome email
      rspec ./spec/controllers/users_controller_spec.rb:351 # UsersController GET confirm_with_token with valid token sends the welcome email to the user
      rspec ./spec/controllers/searches_controller_spec.rb:19 # SearchesController GET search GET search with specific category selected returns the matching OR partial-matching table row objects
      rspec ./spec/controllers/searches_controller_spec.rb:22 # SearchesController GET search GET search with specific category selected only returns values from the selected category
      rspec ./spec/lib/tasks/scheduler_spec.rb:75 # scheduler :wipe_abandoned_images for abandoned images under 1 week old leaves the image
      rspec ./spec/lib/tasks/scheduler_spec.rb:68 # scheduler :wipe_abandoned_images for abandoned images over 1 week old deletes the images
      rspec ./spec/lib/tasks/scheduler_spec.rb:84 # scheduler :wipe_abandoned_images for claimed images leaves the image
      rspec ./spec/controllers/forgot_passwords_controller_spec.rb:24 # ForgotPasswordsController POST create with valid email provided sets the email subject to notify the user of the reset link
      rspec ./spec/controllers/forgot_passwords_controller_spec.rb:27 # ForgotPasswordsController POST create with valid email provided sends the link with token in the body of the email
      rspec ./spec/controllers/forgot_passwords_controller_spec.rb:21 # ForgotPasswordsController POST create with valid email provided sends the reset email to the users provided email
      rspec ./spec/controllers/reset_passwords_controller_spec.rb:70 # ResetPasswordsController POST create with a valid token sets the email subject to notify the user of the reset password
      rspec ./spec/controllers/reset_passwords_controller_spec.rb:67 # ResetPasswordsController POST create with a valid token sends a confirmation email to the user that their password has been changed
      rspec ./spec/controllers/reset_passwords_controller_spec.rb:73 # ResetPasswordsController POST create with a valid token sends the link with token in the body of the email
      

1 个答案:

答案 0 :(得分:1)

我无法解释导致错误的原因。但这必须归功于全局设置Sidekiq测试模式。从规范的head部分删除Sidekiq设置并尝试以下操作:

    before do 
    Sidekiq::Testing.inline! do
      post :create, email: 'jen@example.com' 
     end  
    end
    after do
      ActionMailer::Base.deliveries.clear
      Sidekiq::Worker.clear_all
    end

    it 'sends the reset email to the users provided email' do
      expect(ActionMailer::Base.deliveries.count).to eq(1)
    end