Rspec - Случайная спецификация прошла или не прошла - PullRequest
0 голосов
/ 15 февраля 2019

On 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

Есть что-нибудь подозрительное?

Помощь будет высоко ценится

ВСЕ ОБНОВЛЕНИЕ И ОЧИСТКА

  • Поэтому я удалил все из 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 голосов
/ 15 февраля 2019

Для Rails 5.1+ DatabaseCleaner больше не требуется (для большинства ситуаций), поскольку Rails был обновлен для безопасного совместного использования соединения с базой данных между потоком (ами) AUT и потоком тестирования.Удалите все ссылки на DatabaseCleaner из вашего приложения и установите для use_transactional_fixtures значение true.Он не только будет более корректно изолировать ваши тесты друг от друга, но и обеспечит небольшое ускорение, поскольку данные никогда фактически не передаются в БД.

Кроме того, вам действительно следует отказаться от использования capybara-webkit (в значительной степенина данный момент устарел) на селен с хромом без головы или один из более новых, прямо на Chrome, используя драйверы CDP, такие как apparition и т. д.

Примечание: вы можете использовать опцию --seedrspec, чтобы указать начальное число, используемое во время неудачного запуска, и параметр --bisect, чтобы RSpec определил, какой тестовый прогон раньше вызывает сбой.Это может помочь определить, какой код создает дополнительные данные в БД.

0 голосов
/ 15 февраля 2019

Попробуйте изменить config.use_tranactional_fixtures = true.Ваши ошибки будут зависеть от данных, поэтому очистка БД между примерами должна вам помочь.Это вводящее в заблуждение имя .

...