Rspec-随机规格通过或失败

时间:2019-02-14 21:22:06

标签: ruby-on-rails rspec capybara

在Rails 5.2.2中,我正在使用 RSpec 水豚

与套件一起启动时,我有一些随机规格失败。我相信这取决于它们的运行顺序... (尽管它们都是单独通过的)

我愿意,不管行不通...

bin/rails db:drop db:create db:migrate RAILS_ENV=test
spring stop

我也在使用 DatabaseCleaner ,但是我不确定它是否运行良好。

我在 rail_helper.rb

中调用该文件
    ENV['RAILS_ENV'] ||= 'test'

require File.expand_path('../../config/environment', __FILE__)
require 'rspec/rails'
require 'support/factory_bot'
require 'support/database_cleaner'
require 'devise'

Dir[Rails.root.join('spec/support/**/*.rb')].each { |file| require file }

def login_as(user)
  visit "/users/sign_in"
  fill_in "user[email]", with: user.email
  fill_in "user[password]", with: "password"
  click_on 'login'
end


CarrierWave.configure do |config|
  config.root              = Rails.root.join('spec/fixtures')
  config.cache_only        = true
  config.enable_processing = false
  config.base_path         = "/"
end


RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::IntegrationHelpers, type: :request
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = false
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
end

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

Capybara.javascript_driver = :webkit

Capybara::Webkit.configure do |config|
  config.block_unknown_urls
end

support / database_cleaner.rb

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  config.append_after :each do |example|
    DatabaseCleaner.clean
    CarrierWave.clean_cached_files!(0)
  end

end

spec_helper.rb

 require "capybara/rspec"

RSpec.configure do |config|

  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end

  config.example_status_persistence_file_path = 'tmp/rspec_examples.txt'
  config.order = :random
  config.shared_context_metadata_behavior = :apply_to_host_groups 

  config.after(:all) do
    if Rails.env.test? 
      FileUtils.rm_rf(Dir["#{Rails.root}/spec/support/uploads"])
    end 
  end
end

有什么可疑的吗?

我们将不胜感激

整个更新和清洁

  • 所以我从 DatabaseCleaner
  • 中删除了所有内容
  • 我更改了config.use_transactional_fixtures = true(它设置为false)
  • 我跑了rspec --seed 30300 --bisect并得到了下面的结果

    Bisect started using options: "--seed 30300"
    Running suite to find failures... (11.63 seconds)
    Starting bisect with 13 failing examples and 54 non-failing examples.
    Checking that failure(s) are order-dependent... failure appears to be order-dependent
    Round 1: bisecting over non-failing examples 1-54 .. ignoring examples 28-54 (12.05 seconds)
    Round 2: bisecting over non-failing examples 1-27 . ignoring examples 1-14 (3.04 seconds)
    Round 3: bisecting over non-failing examples 15-27 . ignoring examples 15-21 (2.88 seconds)
    Round 4: bisecting over non-failing examples 22-27 .. ignoring examples 25-27 (4.86 seconds)
    Round 5: bisecting over non-failing examples 22-24 . ignoring examples 22-23 (2.71 seconds)
    Bisect complete! Reduced necessary non-failing examples from 54 to 1 in 27.66 seconds.
    The minimal reproduction command is:
      rspec './spec/models/dashboard_spec.rb[1:1:1,1:2:1,1:3:1,1:4:1,1:6:1,1:7:1,1:8:1,1:9:1,1:10:1,1:11:1,1:12:1,1
    
    :14:1,1:15:1]' './spec/models/orders_spec.rb[1:1:1]' --seed 30300
    

    我正在测试的模型:

    class Dashboard 
    
     attr_reader :min_date, :max_date
    
     def initialize(params)
        params ||= {}
        @min_date = parsed_date(params[:min_date],Time.now.beginning_of_month.to_date.to_s)
        @max_date   = parsed_date(params[:max_date], (Date.today + 1).to_s)
     end
    
     def users_registration_by_week
        User.group_by_week(:created_at, range: (@min_date..@max_date),time_zone: "Paris", week_start: :mon).count
    end
    
    def users_registration_by_week
        User.group_by_week(:created_at, range: (@min_date..@max_date),time_zone: "Paris", week_start: :mon).count
    end
    
     def articles_added_by_week
       Article.group_by_week(:created_at, range: (@min_date..@max_date),time_zone: "Paris", week_start: :mon).count
    end
    
     def articles_counts
       Article.count
     end
    end
    
  

仪表板上的所有故障都相似,所以我只显示了一个

 1) Dashboard#users_registration_by_week returns the total number of user by week
     Failure/Error: expect(res.values.last).to eq(2)

       expected: 2
            got: 5

   (compared using ==)

这是dashboard_spec.rb的一部分

require 'rails_helper'

RSpec.describe Dashboard, type: :model do
    let(:date_from) { 5.days.ago.to_date }
  let(:date_to)   { Date.tomorrow }

  subject { Dashboard.new(date_from: @date_from, date_to: @date_to) }

    describe "#users_registration_by_week" do 
        it "returns the total number of users by week" do
            create(:user, created_at: 2.weeks.ago)
            create(:user, created_at: 2.day.ago )
            create(:user, created_at: 1.day.ago)

            res = subject.users_registration_by_week

            expect(res.values.last).to eq(2)
        end
    end

     describe "#users_registration_by_month" do 
        it "returns the total number of user by month" do
            create(:user, created_at: 2.day.ago)
            create(:user, created_at: 1.day.ago)

            res = subject.users_registration_by_month

            expect(res.values.last).to eq(2)
        end
    end


describe "#articles_counts" do 
        it "returns the total number of article" do
            create(:article, sizes_attributes: [size_name: "L", quantity: 3, created_at: 3.months.ago])
            create(:article, sizes_attributes: [size_name: "L", quantity: 3, created_at: 1.day.ago])
            create(:article, sizes_attributes: [size_name: "L", quantity: 3, created_at: 1.day.ago])

            res = subject.articles_counts
            expect(res).to eq(3)
        end
    end

    describe "#articles_added_by_week" do 
        it "returns the total number of article" do
            create(:article, created_at: 2.weeks.ago ,sizes_attributes: [size_name: "L", quantity: 3, created_at: 2.weeks.ago])
            create(:article, created_at: 2.day.ago ,sizes_attributes: [size_name: "L", quantity: 3, created_at: 2.day.ago])
            create(:article, created_at: 1.day.ago ,sizes_attributes: [size_name: "L", quantity: 3, created_at: 1.day.ago])

            res = subject.articles_added_by_week

            expect(res.values.last).to eq(2)
        end
    end
end

models / order_spec.rb

require 'rails_helper'


 RSpec.describe Order, type: :model do

    fixtures :articles, :users, :sizes

        before(:each) do 
            @shirt  = articles(:blue_shirt)
            @small  = sizes(:small_blue_shirt)
            @large  = sizes(:large_blue_shirt)
            @john = users(:john)
            @token  = 12345678
            @current_cart ||= ShoppingCart.new(token: @token)
            @order  = Order.create(user_id: @john.id, token: @token, status: "pending", sub_total: 80)
         end

    describe "#count_articles" do 
        it "counts the numbers of similar articles" do 
            order_items_1 = OrderItem.create(order_id: @order.id, article_id: @shirt.id , quantity: 2, size_id: @small.id, price: 20)
            order_items_2 = OrderItem.create(order_id: @order.id, article_id: @shirt.id , quantity: 3, size_id: @large.id, price: 20)

            expect(@order.count_articles).to eq 5
        end
    end

end

2 个答案:

答案 0 :(得分:2)

对于Rails 5.1+,不再需要DatabaseCleaner(在大多数情况下),因为Rails已更新为可以安全地在AUT线程和测试线程之间共享数据库连接。从您的应用中删除所有对DatabaseCleaner的引用,并将use_transactional_fixtures设置为true。它不仅可以更正确地将您的测试相互隔离,而且由于数据实际上从未提交给数据库,因此它应该提供较小的加速。

此外,您确实应该使用capybara-webkit(在这一点上已经过时了)转移到无头铬的硒上,或者使用apparition等CDP驱动程序直接将其更新到Chrome。

注意:可以使用--seed选项来指定运行失败期间使用的种子,而使用--bisect选项可以使RSpec找出导致失败发生的测试运行。这可以帮助缩小正在数据库中创建额外数据的代码的范围。

答案 1 :(得分:0)

尝试更改config.use_tranactional_fixtures = true。您的错误将取决于数据,因此清除示例之间的数据库应该会有所帮助。这是misleading name