Заполнение тестовой базы данных с помощью Minitest-rails, Capybara, Capybara-webkit и Rails 4

Я очень новичок в TDD и решил использовать вышеупомянутые драгоценные камни. Я думаю, что настроил его правильно, так как я могу запускать свои тесты. Однако я не могу понять, как заполнить мою тестовую базу данных из db/seeds.rb. Когда я вызываю

rake db:seed RAILS_ENV=test

в терминале я вижу строки, созданные в базе данных через PGAdmin. Однако, когда я запускаю свои тесты со следующим

rake minitest:all

после этого база данных становится пустой, и в тесте, когда я сохраняю снимок экрана, элементы из базы данных не отображаются во внешнем интерфейсе, как это происходит, когда я нахожусь в разработке.

Мой test_helper.rb содержит следующее.

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require 'minitest/rails/capybara'
require 'minitest/focus'
require 'minitest/colorize'
Capybara.javascript_driver = :webkit

class ActiveSupport::TestCase
  fixtures :all
    DatabaseCleaner.strategy = :transaction

    class MiniTest::Spec
      before :each do
            Rake::Task["db:seed"].invoke
            DatabaseCleaner.start
      end

      after :each do
            DatabaseCleaner.clean
      end
    end
end

И в качестве дополнительного фона мой файл db/seeds.rb (который работает при заполнении вручную с помощью rake)

ProgramIndustry.delete_all
ProgramIndustry.create([
        { name: 'Accounting and finance'},
        { name: 'Banking'},
        { name: 'Construction'},
        { name: 'Education'}
])

Почему база данных не будет заполнена seed.rb при запуске тестов?


person Constant Meiring    schedule 02.10.2013    source источник


Ответы (1)


Ваша база данных пуста, потому что вы используете DatabaseCleaner, который удаляет данные из базы данных. Я предполагаю, что вы хотите, чтобы ваш файл test_helper.rb выглядел так:

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require 'minitest/rails/capybara'
require 'minitest/focus'
require 'minitest/colorize'

Capybara.javascript_driver = :webkit

class ActiveSupport::TestCase
  fixtures :all

  DatabaseCleaner.strategy = :transaction

  before do
    DatabaseCleaner.start
    Rake::Task["db:seed"].invoke # seed after starting
  end

  after do
    DatabaseCleaner.clean
  end
end

Я не знаю о вызове задачи db:seed из хука перед, это кажется подозрительным. Но я не использую DatabaseCleaner, так как предпочитаю использовать фикстуры и транзакции, поддерживаемые ActiveSupport::TestCase.

Я не знаю, почему вы используете DatabaseCleaner, но, видя, что вы используете синтаксис RSpec в Minitest, я предполагаю, что вы просто пробуете что-то, пока оно не сработает. Могу ли я предложить отказаться от DatabaseCleaner и поместить все ваши тестовые данные в фикстуры и использовать следующее для управления транзакциями базы данных между потоками:

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require 'minitest/rails/capybara'
require 'minitest/focus'
require 'minitest/colorize'

class ActiveSupport::TestCase
  fixtures :all
end

# Capybara driver
Capybara.javascript_driver = :webkit

# Make all database transactions use the same thread
ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
  def current_connection_id
    Thread.main.object_id
  end
end

И если у вас есть проблемы с этим, рассмотрите этот вариант:

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "rails/test_help"
require "minitest/rails"
require 'minitest/rails/capybara'
require 'minitest/focus'
require 'minitest/colorize'

class ActiveSupport::TestCase
  fixtures :all
end

# Capybara driver
Capybara.javascript_driver = :webkit

# Make all database transactions use the same thread
class ActiveRecord::Base
  mattr_accessor :shared_connection
  @@shared_connection = nil

  def self.connection
    @@shared_connection || retrieve_connection
  end
end

ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
person blowmage    schedule 02.10.2013
comment
Ууууу! Спасибо, это работает. Да, я, очевидно, понятия не имею, что делаю. :D - person Constant Meiring; 03.10.2013
comment
У меня та же проблема, но я не использую DatabaseCleaner, и мы не используем фикстуры. Я пробовал миллионы вещей. Я быстро приближаюсь к моменту, когда отказываюсь от заполнения тестовой базы данных: P - person jaydel; 23.10.2013
comment
@jaydel Свяжитесь со мной, возможно, я смогу помочь. - person blowmage; 23.10.2013
comment
это вызывает ошибку для меня. Это соединение используется: ...webrick/server.rb. Решит ли это проблему несинхронизации тестов capybara webkit с моими контроллерами db? Контроллер создает запись, но мои тесты водосвинки ее не видят. - person John Pollard; 14.12.2016
comment
С Rails 5 работает только второй вариант разделения соединения. - person gertas; 18.12.2016