Rails 5 - 无法清理测试DB

时间:2017-12-06 15:34:15

标签: ruby-on-rails ruby rspec

我最近开始使用RSpec测试我的应用。作为我的测试菜鸟,我没有安装人们通常使用的全套工具(即FactoryGirl,现在也称为FactoryBotDatabaseCleaner)。

无论如何,这里发生了什么。在用RSpec弄湿我之后,我开始使用FactoryBot,这样我的测试看起来就不那么复杂了。请注意,:userDevise对象。

# spec/models/first_test_spec.rb

FactoryBot.create(:user) 
#Other Code

所以我用我的first_test_spec.rb做的事情,然后我运行它,一切都很好。然后我创建我的第二个spec文件

# spec/models/second_test_spec.rb

FactoryBot.create(:user)
#Other Code

现在问题来了。我的测试失败,因为FactoryBot.create(:user)无效,因为Devise需要唯一的电子邮件。显然,这表明来自first_test_spec的数据持续存在,因此出现错误。

所以我尝试安装DatabaseCleaner并希望在每次运行后清除我的测试数据库。我的rails_helper看起来像这样:

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'support/factory_bot'

# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = false

  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.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
end

我认为我已经正确设置了所有内容,因此我不确定错误是否因我的DatabaseCleaner设置错误而仍然存在。

无论如何,运行rspec仍然会抛出相同的错误,其中second_test_spec无法创建user对象,因为电子邮件已经存在(Devise本身附带的验证)。

然后我继续运行以下内容:

rake db:test:prepare
rspec spec/models/second_test_spec.rb

它仍然会引发同样的错误。所以现在,我不知道运行rspec后我的数据库是否正在清理。但我很确定我无法清除我的测试数据库。

所以我想我真的有两个问题/问题:

1)如何清除测试数据库? (谷歌搜索显示rake db:test:prepare就是这样)

2)我的DatabaseCleaner设置正确吗?如果是这样,不应该清除数据库吗?

更新: 正如在评论中向我建议的那样,建议使用sequence创建带有FactoryBot的唯一字段。显然,这会使问题消失,因为Devise不再存在验证错误。

然后我继续测试了几件事。

  1. rails c test 我运行它来检查我的测试数据库,它确实是空的。这表明DatabaseCleaner工作正常。那么我无法理解的是,为什么需要在FactoryBot中对我的电子邮件创建进行排序?或者我想,我不明白RSpec"编译&运行&#34 ;.

  2. puts @user.email 所以我想打印出电子邮件来查看排序,看看我是否能够破译这个问题。这里发生了什么:

  3. 正在运行rspec spec/models/first_test_spec.rb 导师电子邮件产生的数字为2。

    正在运行rspec spec/models/second_test_spec.rb 导师电子邮件产生数字3。

    正在运行rspec 导师电子邮件产生数字2& 5.

    所以我不确定是否存在"问题"用我的测试套件。很明显,我的原始问题已得到解决,这是一个单独的主题。但我想,如果有人想向其他任何有机会可能希望这样做的人解释这个谜。

1 个答案:

答案 0 :(得分:1)

查看完整的spec文件会有所帮助。如果您正在运行您编写的规范 - 在示例组或之前的块之外创建用户 - 这将导致记录被写入清除策略范围之外,并且可能导致数据保留在示例之间。你的DBcleaner配置看起来设置得很好。

transactionDate memberId 1111 1 #I get 1 for my answer since the max date of 1111 is 2017-12-05 2222 3 3333 0 是清除测试数据库的正确方法,但除非您有迁移更改,否则不需要经常运行。您可以跳转到测试环境rake db:test:prepare内的rails控制台,环顾四周,看看是否留下任何记录。

作为旁注,您可以将rails c testconfig.use_transactional_fixtures翻转到false,并从您的应用中完全删除DBcleaner。在进入此路线之前,请确保数据库中没有残留数据。