database_cleaner没有清除我的一些测试(rspec,capybara,selenium)

时间:2012-08-16 22:47:22

标签: ruby-on-rails rspec capybara

database_cleaner在很大程度上起作用,但是在某些事情上,我希望在每次测试后它都不会像user_id那样清除。因此,user_id将在整个过程中递增而不是清除,并且用户ID可预测为1,2,3或为测试创建的许多。我可以调用id而不是硬编码预期的结果但后来我真的需要它来清除更复杂的例子中的东西。这是最容易展示的。任何帮助将不胜感激。

FROM SPEC_HELPER.RB:

RSpec.configure do |config|

  config.mock_with :rspec
  config.include FactoryGirl::Syntax::Methods

  config.include(Capybara, :type => :integration)
  config.include Devise::TestHelpers, :type => :controller
  config.use_transactional_fixtures = false

  config.before(:each) do
    I18n.default_locale = :en
    I18n.locale = :en
    DatabaseCleaner.start
    ResqueSpec.reset!
    ActionMailer::Base.deliveries.clear
  end 

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

  config.after(:all) do
    TestCleaner.clean
  end

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
    DatabaseCleaner.strategy = :transaction
    Role.reset_cache!
  end

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

来自我的测试:

      it "should return one provider" do
        get :index

        response.body.gsub(/\s+/, "").should == {
            :experts => [{
                             :availability => false,
                             :name => "#{@provider.user.first_name}#{@provider.user.last_name}",
                             :expert_id => 1,
                             :photo => @provider.details.photo.url
                         }] }.to_json
      end

      it "should show return two providers"  do
        @provider2 = create(:provider)
        get :index

        response.body.gsub(/\s+/, "").should == {
            :experts => [{
                             :availability => false,
                             :name => "#{@provider.user.first_name}#{@provider.user.last_name}",
                             :expert_id => 1,
                             :photo => @provider.details.photo.url
                         },
                         {
                             :availability => false,
                             :name => "#{@provider.user.first_name}#{@provider.user.last_name}",
                             :expert_id => 2,
                             :photo => @provider.details.photo.url
                         }
            ] }.to_json
      end

3 个答案:

答案 0 :(得分:3)

数据库清理程序将每个规范包装在事务中,并在规范末尾回滚该事务以删除任何数据库更改。回滚事务不会重置用于自动分配主键的自动增量或序列值。

我强烈建议不要对ID进行硬编码。你提到你的例子会变得更复杂,在这种情况下,通过代码散布的随机整数将比简单的例子更难维护。假设您正在使用mysql,那么使用截断策略将重置自动增量值,但它也会慢得多。

答案 1 :(得分:1)

数据库未正确清理的请求/集成规范是什么?如果是这样,可能是因为您使用事务策略清理而不是截断策略。

尝试添加此选项,这会将策略更改为仅针对集成规范进行截断:

config.before type: :integration do
  DatabaseCleaner.strategy = :truncation
end

您不能对集成规范使用事务策略,因为Capybara在具有不同数据库连接的单独线程中运行。

这篇文章帮助我设置了rspec / capybara的数据库内容:Sane Rspec config for clean, and slightly faster, specs

答案 2 :(得分:1)

开始测试时我遇到了很多。我最终发现它不是由于数据库更清洁的问题(我也怀疑),而是由于代码的结构进行了测试。

我可以尝试和描述的最佳方式是,基本上如果您在before(:each)设置块之外执行操作并且实际itshould最终是实际测试的“外部”并导致这些问题。

具体来说,我怀疑这里可能存在问题:

  it "should show return two providers"  do
    @provider2 = create(:provider)
    get :index

    response.body.gsub(/\s+/, "").should == {

我希望将此更改为更像:

  it "should show return two providers"  do
    before(:each) do { 
      @provider2 = create(:provider)
      get :index
    }

    response.body.gsub(/\s+/, "").should == {