Rspec - 随机规范通过或失败

问题描述 投票:0回答:2

在Rails 5.2.2我使用的是RSpec和Capybara

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

我这样做,有效与否......

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

支持/ 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

有什么可疑的吗?

非常感谢帮助

WHOLE UPDATE AND CLEANING

  • 所以我从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

车型/ 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
ruby-on-rails rspec capybara
2个回答
2
投票

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

此外,你真的应该使用capybara-webkit(在这个时间点已经过时)转移到使用无头镀铬的硒或使用像apparition等CDP驱动程序的新版Chrome之一。

注意:您可以使用--seed选项来指定失败运行期间使用的种子和--bisect选项,以使RSpec确定在导致失败之前的哪个测试运行。这可以帮助缩小哪些代码在DB中创建额外数据的范围。


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.