在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
有什么可疑的吗?
我们将不胜感激
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
答案 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。